读Javascript MDN之闭包

闭包

  闭包是(函数)和(声明该函数的词法环境)的组合。

  

例子

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用,而 displayName实例仍可访问其词法作用域中的变量,即可以访问到 name 。由此,当 myFunc 被调用时,name 仍可被访问,其值 Mozilla 就被传递到alert中。

例子

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

我们定义了 makeAdder(x) 函数,它接受一个参数 x ,并返回一个新的函数。返回的函数接受一个参数 y,并返回x+y的值。

从本质上讲,makeAdder 是一个函数工厂 — 他创建了将指定的值和它的参数相加求和的函数。在上面的示例中,我们使用函数工厂创建了两个新函数 — 一个将其参数和 5 求和,另一个和 10 求和。

add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。

模拟私有方法

我们可以使用闭包来模拟私有方法。私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。

下面的示例展现了如何使用闭包来定义公共函数,并令其可以访问私有函数和变量。这个方式也称为 模块模式(module pattern):

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

我们只创建了一个词法环境,为三个函数所共享:Counter.increment,Counter.decrement 和 Counter.value

MDN打不开了,公司的网络666

近期遇到的面试题:闭包的优点和缺点。当时就回了句不清楚,早前也接触过知道一些,但是并不能用语言表示出来。

优点:闭包环境可以定义私有变量。

缺点:在闭包内var声明的变量不能自动释放。

解决方法:将声明的变量写成构造器或是使用对象字面量的方式书写,这个主要是为了改变函数内this指向,使delete能成功。(看到觉得理解不对的请指出!!!!!)

......................................我是不写闭包,但我能用别的方法达到类似的效果。

面试遇到这种考察原生基础的,不会答,很烦。

  

原文地址:https://www.cnblogs.com/Merrys/p/9429010.html