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

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

通过构造器创建的函数的[[scope]]

在上面的例子中,我们看到,在函数创建时获得函数的[[scope]]属性,通过该属性访问到所有父上下文的变量。但是,这个规则有一个重要的例外,它涉及到通过函数构造器创建的函数。

var x = 10;
function foo() {
  var y = 20;
  function barFD() { // FunctionDeclaration
    alert(x);
    alert(y);
  }
  var barFE = function () { // FunctionExpression
    alert(x);
    alert(y);
  };
  var barFn = Function('alert(x); alert(y);');
  barFD(); // 10, 20
  barFE(); // 10, 20
  barFn(); // 10, "y" is not defined
}
foo();

我们看到,通过函数构造器Function constructor)创建的函数“bar”,变量“y”不能访问。但这并不意味着函数“barFn”没有[[scope]]属性(否则它不能访问到变量“x”)。问题在于通过函数构造器创建的函数的[[scope]]属性总是包含唯一的全局对象。考虑到这一点,如通过这种函数创建除全局之外的最上层的上下文闭包是不可能的。

二维作用域链查找

在作用域链中查找最重要的一点是变量对象的prototype(如果有的法)须考虑其中--源于ECMAScript 的原型特性。如果在对象中没有直接找到,查询将在原型链中继续。即常说的二维链查找。(1)作用域链环节;(2)每个作用域链--深入到原型链环节。如果在Object.prototype 中定义了属性,我们能看到这种效果。

function foo() {
  alert(x);
}
Object.prototype.x = 10;
foo(); // 10

激活对象没有原型,我们可以在下面的例子中看到:

function foo() {
  var x = 20;
  function bar() {
    alert(x);
  }
  bar();
}
Object.prototype.x = 10;
foo(); // 20

如果函数“bar”上下文的激活对象有一个原型,那么“x”将在Object.prototype 中被解析,因为它在AO中不被直接解析。但在上面的第一个例子中,在标识符解析中,我们到达全局对象(在一些执行中并不全是),他从Object.prototype继承而来,响应地,“x”解析为10。

同样的情况出现在一些版本的SpiderMokey 的命名函数表达式(缩写为NFE)中,在那里特定的对象存储从Object.prototype继承而来的函数表达式的可选名称,在Blackberry中的一些版本中,执行时激活对象从Object.prototype继承。但是,关于此特色的更多细节在Chapter 5. Functions.讨论。

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