闭包和ES2015

时间:2015-11-19 11:31:38

标签: javascript closures ecmascript-6

我提前为另一个关闭问题道歉,但我想澄清一下我对用JavaScript实现闭包的方式的理解。

请考虑以下代码:

01 'use strict';
02 function foo() {}
03 foo();

我在今年早些时候在question建立了一个闭包在概念上(如果不是实际上由于引擎优化)在这里创建。

在第3行调用foo之前,不会创建相应的执行上下文。

据我所知,在评估此代码时:

  1. 每个执行上下文都有一个“LexicalEnvironment”组件,用于解析其中的代码所引用的标识符引用(8.3,表23)。
  2. 调用
  3. FunctionCreate,将引用(名为“scope”)传递给当前执行上下文的“LexicalEnvironment”组件。 (19年1月14日)
  4. FunctionCreate调用FunctionInitialize传递“范围”(9.2.5)
  5. FunctionInitialize确保正在创建的函数对象的 [[Environment]] 内部插槽设置为“scope”的值(对“LexicalEnvironment”组件的引用)当前执行上下文)(9.2.4)
  6. 最后,当实际调用foo时,我发现规范难以解释。

    1. PrepareForOrdinaryCall中,调用的新执行上下文的“LexicalEnvironment”设置为调用NewFunctionEnvironment(9.2.1.1)的结果
    2. NewFunctionEnvironment将对外部执行上下文的“LexicalEnvironment”组件(函数对象的 [[Environment]] 插槽)的引用复制到Environment正在构建的执行上下文的“LexicalEnvironment”组件的记录(EnvironmentRecord?)作为“外部词汇环境参考”(8.1.2.4)
    3. 因此,闭包以两步方式实现:

      1. 在函数对象实例化时创建函数对象与封闭执行上下文的封闭“LexicalEnvironment”之间的链接。这是函数对象的 [[Environment]] 内部插槽。
      2. 当调用函数时,对外部执行上下文的封闭“LexicalEnvironment”组件(函数对象的 [[Environment]]槽的内容)的引用被复制到新执行上下文的“LexicalEnvironment”组件的spec-imprecisely-defined(?)/ EnvironmentRecord(?)子组件。
      3. 这听起来不错吗?

1 个答案:

答案 0 :(得分:1)

  

这听起来不错吗?

差不多。我只是不会使用“复制”的工作,而是“链接”。为了简化它:

  1. 创建函数时,它存储对它所创建的环境的引用。
  2. 执行该功能时,该存储环境成为新创建的功能环境的“外部环境”。
  3. 或者在图片中:

                      +----------------+                     +----------------+
       Function       |                |   [[Environment]]   |     Outer      |
       creation       |    Function    |-------------------->|  Environment   |
                      |                |                     |                |
                      +----------------+                     +----------------+
                                                                      ^        
                                                                      |        
                                                                      |        
                      +----------------+                              |        
       Function       |    Function    |  outer environment reference |        
       execution      |  Environment   |------------------------------+        
                      |                |                                       
                      +----------------+                                       
    

    每个函数都会发生这种情况,并且根据你对闭包 1 的定义,这会使每个函数成为闭包(或不是)。

    1:我相信有两个关于函数成为闭包的意义:

    • 如果函数存储对其创建的环境的引用,则它是一个闭包(适用于JS中的每个函数)
    • 如果一个函数存储了对环境的引用,那么它是在“中”创建的那个环境(环境“不再存在”)中创建的,它就是一个闭包。当然并非总是如此。