软件下载 | 资讯教程 | 最近更新 | 下载排行 | 一键转帖 | 发布投稿
您的位置:最火下载站 > Web前端 > Ajax/JavaScript > ECMA-262-3 深入解析.第四章.作用域链(5)

ECMA-262-3 深入解析.第四章.作用域链(5)

全局和eval上下文中的作用域链

这里不一定很有趣,但必须要提示一下。全局上下文的作用域链仅包含全局对象。代码eval用同样的作用域链作为调用上下文(calling context )。

globalContext.Scope = [
  Global
];
evalContext.Scope === callingContext.Scope;

代码执行时对作用域链的影响

在ECMAScript 中,在代码执行阶段有两个声明能修改作用域链。这就是with声明catch语句。它们添加到作用域链的最前端,对象须在这些声明中出现的标识符中查找。如果发生其中的一个,作用域链简要的作如下修改:

Scope = withObject|catchObject + AO|VO + [[Scope]]

在这个例子中添加对象,对象是它的参数(这样,没有前缀,这个对象的属性变得可以访问)。

var foo = {x: 10, y: 20};
with (foo) {
  alert(x); // 10
  alert(y); // 20
}

我们再次看到,通过with语句,对象中标识符的解析添加到作用域链的最前端:

var x = 10, y = 10;
with ({x: 20}) {
  var x = 30, y = 30;
  alert(x); // 30
  alert(y); // 30
}
alert(x); // 10
alert(y); // 30

在进入上下文时发生了什么?标识符“x”和“y”已被添加到变量对象中。此外,在代码运行阶段作如下修改:

  • x = 10, y = 10;
  • 对象{x:10}添加到作用域的前端;
  • 在with内部,遇到了var声明,当然什么也没创建,因为在进入上下文时,所有变量已被解析添加;
  • 在第二步中,仅修改变量“x”,实际上对象中的“x”现在被解析,并添加到作用域练得最前端,“x”为20,变为30;
  • 同样也有变量对象“y”的修改,被解析后其值也相应的由10变为30;
  • 此外,在with声明完成后,它的特定对象从作用域链中移除(已改变的变量“x”--30也从那个对象中移除),即作用域链的结构恢复到with得到加强以前的状态。
  • 在最后两个alert中,当前变量对象的“x”保持同一,“y”的值现在等于30,在with声明运行中已发生改变。

同样,catch语句的异常参数变得可以访问,它创建了只有一个属性的新对象--异常参数名。图示看起来像这样:

try {
  ...
} catch (ex) {
  alert(ex);
}

作用域链修改:

var catchObject = {
  ex: <exception object>
};
Scope = catchObject + AO|VO + [[Scope]]

在catch语句完成运行之后,作用域链恢复到以前的状态。

结论

在这个阶段,我们几乎考虑了与执行上下文相关的所有常用概念,以及与它们相关的细节。按照计划--函数对象的详细分析:函数类型(FunctionDeclaration, FunctionExpression)和闭包。顺便说一下,在这篇文章中,闭包直接与[[scope]]属性相关,但是,关于它将在合适的篇章中讨论。我很乐意在评论中回答你的问题。

其它参考

原文地址:http://dmitrysoshnikov.com/ecmascript/chapter-4-scope-chain/

转载地址:http://www.denisdeng.com/?p=908

相关阅读
栏目导航
推荐软件