为什么内部函数的变量不会泄漏到外部范围?

时间:2012-09-27 09:47:36

标签: javascript

考虑以下JavaScript代码片段:

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

显然,变量youter的上下文中不可用。完成ES5规范中的流程后告诉我们,当我们输入outer执行上下文时会发生这种情况:

  • 我们输入新的执行上下文(10.4

  • 由于这是一项功能,我们会按照Entering Function Code (10.4.3)

    中列出的步骤进行操作
    • 代码 F 的[[代码]]内部属性的值。

Creating Function Objects (13.2)中描述了函数的[[Code]]内部属性。它引用语法指定的 FunctionBody (函数的全部内容):

  

function 标识符 ( FormalParameterList opt ) { FunctionBody }

此时我们输入Declaration Binding Instantiation (10.5)部分并执行以下操作:

  • 为函数

  • 的形式参数列表中的任何参数创建绑定
  • 对于代码中的每个函数声明:

    • 在当前范围内创建函数标识符和Function对象(按Function Definition (13)中指定的方式创建)

    • 之间的绑定
    • 没有什么可说的“删除我们刚从代码处理的功能”

  • arguments对象

  • 创建绑定
  • 对于代码中的每个变量声明:

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

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


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

2 个答案:

答案 0 :(得分:1)

你的想法有误。

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

引用spec

  

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

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

答案 1 :(得分:0)

它就在definition of the term code (§10.1)

  

功能代码是作为FunctionBody的一部分进行解析的源文本。特定FunctionBody功能代码不包含任何被解析为嵌套 {{3}的一部分的源文本}。