Geek-James/Blog

7.彻底搞懂-JavaScript 闭包

Geek-James opened this issue · 0 comments

什么是闭包

闭包是指有权访问另一个 函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数,如下代码

function createComparisonFunction(propertyName) {
       return function (object1,object2) {
           var value1 = object1[propertyName];
           var value2 = object2[propertyName];
           if (value1 <value2) {
               return -1;
           } else if (value1>value2) {
               return 1;
           } else {
               return 0;
           }
       };
    }
  • 在这个例子中,突出的那两行代码是内部函数(一个匿名函数)中的代码,这两行代码访问了外部 函数中的变量 propertyName。即使这个内部函数被返回了,而且是在其他地方被调用了,但它仍然可 以访问变量 propertyName。之所以还能够访问这个变量,是因为内部函数的作用域链中包含 createComparisonFunction()的作用域。要彻底搞清楚其中的细节,必须从理解函数被调用的时候 都会发生什么入手。

  • 当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。 然后,使用 arguments 和其他命名参数的值来初始化函数的活动对象(activation object)。但在作用域 链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,......直至作为作用域链终点的全局执行环境。

  • 无论什么时候在函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。一般来讲, 当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。 但是,闭包的情况又有所不同。

  • 由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过 度使用闭包可能会导致内存占用过多,我们建议读者只在绝对必要时再考虑使用闭 包。虽然像 V8 等优化后的 JavaScript 引擎会尝试回收被闭包占用的内存, 还是要慎重使用闭包。

  • js闭包概念的深入了解

  • 浅谈JavaScript中的闭包(closure)