函数表达式是否具有自己的范围/词法环境

时间:2013-02-22 22:37:58

标签: javascript scope ecmascript-5 ecma262

我正在阅读ECMA 262 5 specification的执行上下文/词汇环境部分。它陈述如下:(强调添加)

  

词汇环境是一种规范类型,用于根据ECMAScript代码的词法嵌套结构定义标识符与特定变量和函数的关联。词汇环境由环境记录和外部词汇环境的可能空引用组成。通常,词汇环境与ECMAScript代码的某些特定语法结构相关联,例如 FunctionDeclaration ,WithStatement或TryStatement的Catch子句,并且每次评估此类代码时都会创建新的词法环境。

我注意到它没有说明为函数表达式创建词法环境。是为函数表达式创建的词法环境,还是仅为函数声明创建的?我错过了什么吗?

编辑:我注意到函数代码会有its own execution context,这就是为什么我也很困惑为什么在词法环境部分没有提到函数表达式。

3 个答案:

答案 0 :(得分:3)

是的,每个函数在调用(§10.4.3)时都会获得(§13.2.1)自己的ExecutionContext。新的上下文初始化为新的LexicalEnvironment(由NewDeclarativeEnvironment§10.2.2.2创建),派生自函数的[[Scope]] - 即LexicalEnvironment它是{{1}}在(§13)声明/“表达”。

正如@Pointy指出的那样,你所说的句子没有详尽地列出它们:“ ......某些[结构]如...... ”。

答案 1 :(得分:3)

如果某个名称包含在 FunctionExpression 中,则该名称将成为一个只读绑定,它会隐藏同名的任何外部声明。但是该绑定本身可能会被函数中的形式参数或本地声明所掩盖。函数名的这种绑定仅为命名的 FunctionExpressions 创建,而不是为匿名 FunctionExpressions FunctionDeclarations 创建。 FunctionDeclaration 的名称绑定是在周围的VariableEnvironment中创建的。

以下是参考ES5.1规范的更详细说明:

有多个与功能对象关联的环境记录。每当调用一个函数时,都会创建一个新的DeclarativeEnvironmentRecord来包含该特定函数调用的本地绑定。该记录同时成为VariableEnvironment和为该调用创建的ExecutionContext的初始LexicalEnvironment。这在第10.4.3节中规定。

创建此环境记录时,其“外部环境”设置为正在调用的函数对象的[[Scope]]内部属性的值。 (第5,10.4.3节)外部环境为所有非本地声明提供绑定。 [[Scope]]在创建函数对象时设置(参见第13节和13.2中的语义)。因此,特定函数对象的每个不同调用都具有不同的本地环境,但该函数的所有调用共享相同的外部[[Scope]]。

对于大多数函数,捕获的[[Scope]]只是在创建函数时处于活动状态的ExecutionContext的LexicalEnvironment。但是,包含标识符作为函数名称的 FunctionExpressions 在其[[Scope]]链的头部有一个额外的DeclarativeEnvironmentRecord插入。 (参见第13节中第三种算法的步骤1-3)。

此额外环境记录用于捕获 FunctionExpression 中给出的函数名称的绑定。

答案 2 :(得分:2)

实例化函数具有范围。它是否被实例化为函数声明语句或函数实例化表达式的一部分并不重要。

(说实例化函数在调用时具有范围,并且每次调用都会产生不同范围时,可能更为正确。)