我提前为另一个关闭问题道歉,但我想澄清一下我对用JavaScript实现闭包的方式的理解。
请考虑以下代码:
01 'use strict';
02 function foo() {}
03 foo();
我在今年早些时候在question建立了一个闭包在概念上(如果不是实际上由于引擎优化)在这里创建。
在第3行调用foo
之前,不会创建相应的执行上下文。
据我所知,在评估此代码时:
FunctionCreate
,将引用(名为“scope”)传递给当前执行上下文的“LexicalEnvironment”组件。 (19年1月14日)FunctionCreate
调用FunctionInitialize
传递“范围”(9.2.5)FunctionInitialize
确保正在创建的函数对象的 [[Environment]] 内部插槽设置为“scope”的值(对“LexicalEnvironment”组件的引用)当前执行上下文)(9.2.4)最后,当实际调用foo
时,我发现规范难以解释。
PrepareForOrdinaryCall
中,调用的新执行上下文的“LexicalEnvironment”设置为调用NewFunctionEnvironment
(9.2.1.1)的结果NewFunctionEnvironment
将对外部执行上下文的“LexicalEnvironment”组件(函数对象的 [[Environment]] 插槽)的引用复制到Environment
正在构建的执行上下文的“LexicalEnvironment”组件的记录(EnvironmentRecord
?)作为“外部词汇环境参考”(8.1.2.4)因此,闭包以两步方式实现:
EnvironmentRecord
(?)子组件。这听起来不错吗?
答案 0 :(得分:1)
这听起来不错吗?
差不多。我只是不会使用“复制”的工作,而是“链接”。为了简化它:
或者在图片中:
+----------------+ +----------------+
Function | | [[Environment]] | Outer |
creation | Function |-------------------->| Environment |
| | | |
+----------------+ +----------------+
^
|
|
+----------------+ |
Function | Function | outer environment reference |
execution | Environment |------------------------------+
| |
+----------------+
每个函数都会发生这种情况,并且根据你对闭包 1 的定义,这会使每个函数成为闭包(或不是)。
1:我相信有两个关于函数成为闭包的意义: