4

考虑以下 JavaScript 片段:

function outer() {
    var x = 10;
    function inner() {
        var y = 20;
    }
}

显然,该变量y在 的上下文中不可用outerouter遵循 ES5 规范中的流程告诉我们,当我们进入执行上下文时会发生这种情况:

创建函数对象 (13.2)中描述了函数的 [[Code]] 内部属性。它指的是语法指定的FunctionBody (函数的全部内容):

function 标识符 ( FormalParameterList opt ) { FunctionBody }

此时我们进入声明绑定实例化(10.5)部分并执行以下操作:

  • 为函数的形式参数列表中的任何参数创建绑定

  • 对于代码中的每个函数声明:

    • Function在函数标识符和对象之间创建当前范围内的绑定(按照函数定义 (13)中的指定创建)

    • 没有什么可说的“从代码中删除我们刚刚处理的函数”

  • arguments为对象创建绑定

  • 对于代码中的每个变量声明:

    • 在当前范围内为变量标识符创建绑定

我的问题是,为什么此时没有为内部函数的变量声明创建绑定?似乎代码仍应包含外部函数的整个源文本(其中将包括内部函数的源文本)。我正在规范中寻找解释行为的东西。


更新,更清楚一点:我问的是当我们进入outer函数的上下文时会发生什么。该inner函数永远不会被调用,我也不关心当我们从outer函数返回时会发生什么。我完全对规范定义的过程感兴趣,即在进入新的执行上下文时为变量声明创建绑定。

4

2 回答 2

1

你的想法有误。

Javascript具有函数范围。因此,您对每个函数都有一个新的执行上下文,这是真的。但是,从函数返回后,此函数上下文过期。这就是为什么在内部函数返回后您无法从内部函数访问变量的原因。您仍然处于外部函数的执行上下文中,但您无法再访问内部函数的执行上下文。

引用规范

每个返回都退出一个执行上下文。抛出的异常也可能退出一个或多个执行上下文。

编辑:为了进一步澄清这一点:函数声明的主体没有被处理(见10.5.5.d),只有函数标识符和参数被传递给变量环境。

于 2012-09-27T09:54:45.243 回答
0

它就在术语代码(§10.1)的定义中:

函数代码是作为FunctionBody的一部分解析的源文本。特定FunctionBody函数代码包含任何被解析为嵌套FunctionBody一部分的源文本。

于 2017-03-21T23:10:51.080 回答