JS闭包

写在最前
函数和对其周围状态(即词法环境)的引用捆绑在一起构成闭包。所以说,正是因为闭包,内部函数才可以访问外部函数的作用域。
词法作用域

词法作用域就是,声明变量的位置决定了能够使用这个变量的范围。如果理解不了这个词,可以将词法作用域的“法”字看成一个动词,然后再去理解一下前面的这句话应该就能明白了。

闭包

下面是MDN上面的一段代码

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

var myFunc = makeFunc();
myFunc();

调用makeFunc返回了makeFunc的一个内部函数displayName,然后执行。结果浏览器成功alert了name的值。

可以看到,displayName这个函数在执行的时候,makeFunc已经执行完了,当makeFunc执行完之后其内存中的作用域应该已经被销毁了,但为什么这个时候执行displayName还是会成功的获取到name的值呢?就是因为闭包!

JavaScript中的函数是会形成闭包的,闭包是由函数和该函数的词法环境组合而成的,函数的词法环境显然包含了环境内所有的局部变量。当displayName声明的时候,就形成了闭包,displayName这个函数实例会维持一份对它的词法环境(其中包含name)的引用,所以当后面执行对displayName实例的引用的时候,依然可以获取到name的值。

说白了就是,js的变量声明的位置决定了它的使用范围,在这个范围内就确定了谁可以用到这个变量谁会用到这个变量,不管什么时候,需要用到这个变量的方法永远都能获取到这个变量,就算变量作用域被销毁了,它也会维持一份这个变量的内存,以供后续调用。

用闭包模拟私有方法

也是MDN的一个例子,看来让人眼前一亮

JS是没有Java的私有方法的概念的,但很多时候为了避免全局污染,或者是避免非公共方法与公共方法混为一团,我们可以用闭包来模拟私有方法,使用一个闭包来定义一个公共方法,使其拥有和访问自己的私有方法和私有变量,及模块模式。

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。

该共享环境创建于一个立即执行的匿名函数体内。这个环境中包含两个私有项:名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。

这三个公共函数是共享同一个环境的闭包。多亏 JavaScript 的词法作用域,它们都可以访问 privateCounter 变量和 changeBy 函数。

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值