前端杂谈 · Web

JavaScript 闭包

小编 · 4月12日 · 2020年

闭包的概念

JavaScript 采用词法作用域,也就是说,函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。为了实现这种词法作用域,JS 函数对象的内部状态不仅包含函数的代码逻辑,还必须引用当前的作用域链。

JavaScript 闭包

函数对象可以通过作用域链互相关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为 “闭包”。

当一个函数嵌套了另外一个函数,外部函数将嵌套的函数对象作为返回值返回的时候,调用函数时闭包所指向的作用域链和定义函数时的作用域链不是同一个作用域链。

作用域链

我们将 “作用域链 ” 描述为一个对象的链表,而不是绑定的栈。

每次调用 javascript 函数的时候,都会为之创建一个新的对象用来保存局部变量,把这个对象添加至作用域链中。当函数返回时,从作用域链中将这个绑定变量的对象删除。

  • 如果不存在嵌套函数,也没有其他引用指向这个绑定对象,它就会被当垃圾回收掉。
  • 如果定义了嵌套函数,每个嵌套函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象。但如果这些嵌套函数对象在外部函数中保存下来,那么它们也会和所指向的变量绑定对象一样当作垃圾回收。
  • 但是如果这个函数定义了嵌套函数,并将它作为返回值返回或者存储在某处的属性里,这时就会由一个外部引用指向这个嵌套函数。它就不会被当作垃圾回收,并且它所指向的变量绑定对象也不会被当作垃圾回收。
//闭包实现计数器函数
function counter() {
    var n = 0;
    return {
        count: function() { return n++; },
        reset: function() { n = 0 ; }
    };
}
var scope = "global scope";      //全局变量
function checkscope() {
    var scope = "local scope";             //局部变量
    function f() { return scope; }               //在作用域中返回这个值
    return f;
}
checkscope()();

上面的代码中 checkscope ()();返回的值应该是什么呢?

评论后可查看此区域内容
14 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!

  1. 匿名2020-5-15 · 7:00

    ???好

  2. 匿名2020-5-14 · 0:45

    多谢

  3. 匿名2020-5-13 · 17:27

    感谢