Javascript 关闭和ES2015

Javascript 关闭和ES2015,javascript,closures,ecmascript-6,Javascript,Closures,Ecmascript 6,我为另一个闭包问题提前道歉,但我想澄清一下我对JavaScript中闭包实现方式的理解 考虑以下代码: 01 'use strict'; 02 function foo() {} 03 foo(); 我在今年早些时候的一篇文章中已经确定,这里在概念上(如果不是由于引擎优化)创建了一个闭包 在第3行调用foo之前,不会创建相应的执行上下文 从规范中我可以看出,在评估此代码时: 每个执行上下文都有一个“LexicalEnvironment”组件,用于解析其中的代码所做的标识符引用(8.3,表23)

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

考虑以下代码:

01 'use strict';
02 function foo() {}
03 foo();
我在今年早些时候的一篇文章中已经确定,这里在概念上(如果不是由于引擎优化)创建了一个闭包

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

从规范中我可以看出,在评估此代码时:

  • 每个执行上下文都有一个“LexicalEnvironment”组件,用于解析其中的代码所做的标识符引用(8.3,表23)
  • 调用
    FunctionCreate
    ,将引用(名为“scope”)传递到当前执行上下文的“词典环境”组件。(14.1.19)
  • FunctionCreate
    调用
    FunctionInitialize
    传递“范围”(9.2.5)
  • FunctionInitialize
    确保正在创建的函数对象的[[Environment]]内部插槽设置为“scope”(当前执行上下文中对“LexicalEnvironment”组件的引用)(9.2.4)
  • 最后,当实际调用
    foo
    时,我发现规范更难解释

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

  • 函数对象与封闭执行上下文的封闭“词典环境”之间的链接在函数对象实例化时创建。这是函数对象的[[Environment]]内部槽
  • 调用函数时,对外部执行上下文的封闭“LexicalEnvironment”组件(函数对象的[[Environment]]槽的内容)的引用被复制到“LexicalEnvironment”的规范子组件中,该子组件的定义不精确(?)/
    EnvironmentRecord
    (?)“新执行上下文的组件
  • 这听起来对吗

    这听起来对吗

    差不多。我只是不想用“复制的”,而是“链接的”。简化一下:

  • 创建函数时,它存储对创建它的环境的引用
  • 执行函数时,此存储环境将成为新创建的函数环境的“外部环境”
  • 或在图片中:

    +-------------++----------------+
    功能| |[[环境]]|外部|
    创建|功能|----------------->环境|
    |                |                     |                |
    +----------------+                     +----------------+
    ^        
    |        
    |        
    +----------------+                              |        
    功能|功能|外部环境参考|
    执行|环境|-----------------------------------+
    |                |                                       
    +----------------+                                       
    
    这会发生在每个函数上,并且取决于您对closure1的定义,这会使每个函数都成为闭包(或不是闭包)


    1:我认为函数作为一个闭包意味着两个方面:

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

    没有什么可以结束的,那么你到底在哪里看到结束?@zeroflagL我向你提出上述相关问题@zeroflagL严格地说,是的,有一个闭包,但闭包环境中唯一的变量是全局对象。@Alnitak…全局变量实际上不是变量,而是全局对象上的属性,因此闭包中不存在这些属性。仅供参考,全局环境和普通函数环境之间的主要区别在于,全局环境由一个对象而不是某个内部表“支持”。也就是说,正如您所说,全局变量成为全局对象的属性。但是,它的行为仍与任何其他环境类似。它并不特别,它只是处于环境链的末端。全局变量不仅仅是可以神奇地访问的。顺便说一句,
    let
    const
    class
    es在全局范围内定义时不会成为全局对象的属性。是的,每个功能都会在全球环境中关闭。谢谢。我说规范在当前函数调用的执行上下文的“LexicalEnvironment”上留下了不精确的“EnvironmentRecord”命名(实际上是位置)是正确的吗。我说的是函数对象[[Environment]]插槽的目标链接所在的内存位置,我不会说它不精确。规范只是定义了AP