标识符解析
标识符解析是指使用正在运行的执行上下文中的词法环境组件,通过标识符获得其对应的绑定的过程。
换句话说,这一个作用域链查找过程。如前所述,这类似于原型链的查找,而在这里是通过词法环境的outter属性。
看下面这个例子:
var a = 10;
(function foo() {
var b = 20;
(function bar() {
var c = 30;
console.log(a + b + c); // 60
})();
})();
对于标识符a的解析算法过程如下:
function resolveIdentifier(lexicalEnvironment, identifier) {
// 如果这是链的末端,而且没有找到绑定
// 抛出ReferenceError
if (lexicalEnvironment == null) {
throw ReferenceError(identifier + " is not defined");
}
//返若是存在回绑定,一个reference类型的值
// 稍后我们能从这个reference中获取绑定值
if (lexicalEnvironment.hasBinding(identifier)) {
return new Reference(lexicalEnvironment, identifier);
}
//或者寻找父作用域
//递归的寻找外部环境
return resolveIdentifier(lexicalEnvironment.outer, identifier);
}
resolveIdentifier(bar.[[LexicalEnvironment]], "a") ->
-- bar.[[LexicalEnvironment]] - not found,
-- bar.[[LexicalEnvironment]].outer (i.e. foo.[[LexicalEnvironment]]) -> not found
-- bar.[[LexicalEnvironment]].outer.outer -> found reference, value 10
结论
这一章我们讨论ECMAScript中词法环境的概念。同样解释了为什么要把老版概念中变量/激活 对象以及作用域链变成现在的链式词法环境----最重要的原因是新的定义带来更高效的实现。
我们也看到了,词法环境和闭包紧密关联在一起(再次说明,ECMAScript中函数表达式和函数声明都是闭包)。再次解释this的概念以及它在不同执行上下文是如何运作的。
此外,我们也说了一些在未来ES版本中计划实现的东西。例如,移除全局对象。希望上一章的词法环境通用理论介绍能够帮助你了解这些概念的细节。
附录
额外阅读链接:
ECMA-262-5 specification:
- 10.2 Lexical Environments
- 10.2.1 Environment Records
- 10.2.1.1 Declarative Environment Records
- 10.2.1.2 Object Environment Records
- 10.2.2.1 GetIdentifierReference
- 10.3 Execution Contexts
- 10.3.1 Identifier Resolution
扩展阅读
其他
原文链接
ECMA-262-5 in detail. Chapter 3.2. Lexical environments: ECMAScript implementation.