【问题标题】:When a parent lexical environment is created创建父词法环境时
【发布时间】:2018-10-23 23:15:07
【问题描述】:

我一直试图了解何时在 js 中创建词法环境。据我所知,词法环境是分两个阶段创建的,创建阶段和执行阶段,但看看下一个简单的闭包。

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);

so ,当 makeAdder 返回函数时,它返回一个带有指向 x 的父词法环境的函数,但我不明白的是为什么 add5 已经有一个父词法环境,而返回的内部函数甚至没有还没有执行,所以我可以推断出父词法环境在遇到函数定义(返回函数)时就被附加,这是正确的吗?父词法环境是在代码中声明和到达函数时创建的,而不是在执行时创建的?那么返回的函数的词法环境呢,它的词法环境是在函数 add5 执行时创建的。请原谅我的冗长文本,我只是想澄清一下何时创建父级和本地词汇环境。

提前谢谢各位。

【问题讨论】:

标签: javascript closures


【解决方案1】:

所以我可以推断的是,父词法环境一遇到函数定义(返回函数)就被附加,这是正确的吗?

附加到新创建的函数对象上,是的。

父词法环境是在代码中声明和到达函数时创建的,而不是在执行时创建的?

没有。评估函数定义时,父环境已经存在。父环境是包含函数声明的环境。

在你的例子中:

  • 调用makeAdder 创建环境A,将x 设置为5
  • 内部函数 (function (y) {...}) 已创建并获得对 A 的“引用”。
  • makeAdder(内部函数)的返回值赋值给add5
  • 调用add5 创建环境B其父级设置为A。这是可能的,因为该函数在创建时获得了对 A 的引用。
  • xB 中查找。未找到,因此在 B 的父级 A 中查找它,并在其中定义了它。
  • ...

请原谅我的冗长文本,我只是想澄清一下何时创建父级和本地词法环境。

ECMAScript 中有不同类型的环境,它们都是在不同的时间创建的:

  • 声明性环境:所有其他环境的基础,在评估时创建。
  • 函数环境:在评估函数调用时创建。
  • 全局环境:在评估脚本/初始化运行时时创建。

还有更多,但这些应该是与此问题最相关的。欲了解更多信息,请参阅https://www.ecma-international.org/ecma-262/8.0/index.html#sec-lexical-environments

但是,在每个给定时间,只有 一个 环境是“活动的”(堆栈顶部)。每当创建新环境时,当前活动的环境都会成为其父环境。

The spec defines and uses the following operations for creating new environments:

  • NewDeclarativeEnvironment ( E )
  • NewObjectEnvironment ( O, E )
  • NewFunctionEnvironment ( F, newTarget )
  • NewGlobalEnvironment ( G, thisValue )
  • NewModuleEnvironment ( E )

其中E 是另一个环境(成为新环境的父级),F 是一个函数对象。 NewFunctionEnvironment 从函数对象中获取父环境。 NewGlobalEnvironment 不接受父环境,因为全局环境不能有任何父环境。


注意:环境A还有一个父环境,即全局环境(假设代码在全局范围内进行评估)。全局环境没有父级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多