调用上下文评估形参初始值设定项时的“eval”声明实例化

`eval` declaration instantiation when calling context is evaluating formal parameter initializers

PerformEval 抽象操作下面的注释说:

The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if the calling context is evaluating formal parameter initializers or if either the code of the calling context or the eval code is strict mode code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by let, const, or class declarations are always instantiated in a new LexicalEnvironment.

问题:

“如果调用上下文正在评估形式参数初始值设定项”是什么意思?什么是“参数初始化器”?

Note 3 of 9.2.10 的规范中只有一次提到术语“参数初始化器”。这条注释说:

Parameter Initializers may contain direct eval expressions. Any top level declarations of such evals are only visible to the eval code (10.2). The creation of the environment for such declarations is described in 14.1.22.

我将其解释为如果参数初始化表达式包含 eval 调用,则在该 eval 调用中创建的任何变量都不会在参数范围内实例化。因此,在下面的示例中,我期望抛出 ReferenceError,因为 c 不应在参数范围内实例化:

function t(a = eval('var c = 8'), b = () => c) {
  console.log(b())
}

t() // 8 

但是正如您从控制台输出中看到的那样,我的解释是不正确的。即使 c 是在 eval 调用中创建的,它的值对于 b 定义的 funarg 仍然可见,因此可以打印到控制台。

原来您发现了规范错误!我在 TC39 的 Matrix 聊天中询问,他们创建了一个 PR 来删除这个注释:

https://github.com/tc39/ecma262/pull/2428

注释 中的行为曾经 是正确的,但已于 2017 年在 https://github.com/tc39/ecma262/pull/1046

中删除