考虑以下JavaScript代码片段:
function outer() {
var x = 10;
function inner() {
var y = 20;
}
}
显然,变量y
在outer
的上下文中不可用。完成ES5规范中的流程后告诉我们,当我们输入outer
执行上下文时会发生这种情况:
我们输入新的执行上下文(10.4)
由于这是一项功能,我们会按照Entering Function Code (10.4.3)
中列出的步骤进行操作Creating Function Objects (13.2)中描述了函数的[[Code]]内部属性。它引用语法指定的 FunctionBody (函数的全部内容):
function
标识符(
FormalParameterList opt) {
FunctionBody}
此时我们输入Declaration Binding Instantiation (10.5)部分并执行以下操作:
为函数
对于代码中的每个函数声明:
在当前范围内创建函数标识符和Function
对象(按Function Definition (13)中指定的方式创建)
没有什么可说的“删除我们刚从代码处理的功能”
为arguments
对象
对于代码中的每个变量声明:
我的问题是,为什么在这一点上,没有为内部函数的变量声明创建绑定?似乎代码仍然应该包含外部函数的整个源文本(其中包括内部函数的源文本)。我正在寻找解释行为的规范中的东西。
更新,更清楚:我在询问当我们进入outer
函数的上下文时会发生什么。永远不会调用inner
函数,我不关心从outer
函数返回时会发生什么。我纯粹对规范定义的过程感兴趣,即在输入新的执行上下文时为变量声明创建绑定。
答案 0 :(得分:1)
你的想法有误。
Javascript具有功能范围。因此,每个函数都有一个新的执行上下文,这是真的。但是,从函数返回后,此函数上下文将过期。这就是为什么在返回后不能从内部函数访问变量的原因。您仍处于外部函数的执行上下文中,但您无法再访问内部函数的执行上下文。
引用spec:
每个返回都退出执行上下文。抛出的异常也可能退出一个或多个执行上下文。
编辑:进一步澄清:函数声明的主体未被处理(参见10.5.5.d),只有函数标识符和参数被传递给变量环境。
答案 1 :(得分:0)
它就在definition of the term code (§10.1):
中功能代码是作为FunctionBody的一部分进行解析的源文本。特定FunctionBody的功能代码会不包含任何被解析为嵌套 {{3}的一部分的源文本}。