如果变量在需要时在函数中不可用,那么它将在作用域链中查找(这是一个闭包),但有时它会在原型链中被搜索。我正试着把头包裹起来,当时正在发生这种情况。我想知道是否有人可以为我清除薄雾,或者请我参考一些专门讨论这个主题的文献。
例如,我是否正确地说: - 对象和因此与上下文绑定的公共变量(this)总是在原型链中查找? - 始终在范围链中查找私有变量(即执行上下文中的函数链)? - 当程序同时查看两者时是否有任何情况?
我测试了三种不同的场景(范围链查找,原型查找和没有查找),但不幸的是,它没有足够的帮助到达底部。
var Food = function(){
var t = 1; // for closure
this.timeToPrepare = function(){ // Scope chain lookup
console.log(t * 3);
};
this.timeToMake = function(){ // This is looked up in the prototype chain
console.log(this.t * 3);
};
this.timeToEat = function(t){ //No lookup
console.log(t * 3);
};
};
Food.prototype.t = 2;
(function(){
var pizza = new Food;
pizza.timeToPrepare(); //3
pizza.timeToMake(); //6
pizza.timeToEat(3); //9
})();
谢谢!
答案 0 :(得分:18)
变量 在作用域链上查找,从当前执行上下文开始,然后上升到封闭执行上下文的树。
首先在基础对象上查找 属性 ,然后在该对象的[[Prototoype]]
链(即其内部原型)上查找。
所以,如果你这样做:
foo
foo 将被视为变量并在范围链上查找。变量名永远不会被限定,您无法将它们定向到要查找的特定执行上下文。如果作用域链上有两个具有相同名称的变量,则只能访问首次遇到的变量。沿着链(有一种方法专门用于全局变量),例如
var a = 'global a';
function foo() {
var a = 'local a';
return a;
}
console.log(foo()); // local a
在上面,函数中的 a 解析为局部变量 a 。在全局变量的情况下,它们是全局对象的属性,因此您可以访问它们,即使它们被遮蔽了#34;由同一个命名的本地属性,例如
function foo() {
var = 'local a';
// this will reference the global object
return this.a;
}
console.log(foo()); // global a
相反,属性名称前面总是有一个查找它们的基础对象(如上例所示, this 引用全局对象),例如。
foo.bar
将拆分为 foo 和 bar 。首先, foo 将在范围链上解析,如果找到,属性解析将尝试查找 bar 属性。因此,对于属性,您可以指示查找属性的对象。因此,如果有两个具有相同命名属性的对象,只要两个对象都在范围内,就可以查找这两个属性。
因此,任何引用的第一部分都被视为变量,后续部分被视为属性。除非使用 with ,否则不鼓励使用。不要去那里。
但为了完整性... with 将指定的对象放在起始作用域链上,以便在使用作用域链之前首先将变量作为该对象的属性进行查找,因此您可以这样做:
var cos = function(arg){return 'my cos function: ' + arg};
function foo() {
// cos is resolved on the scope chain
console.log(cos(0.5)); // my cos function: 0.5
with (Math) {
// cos is first resolved as a property of Math, and only on the
// scope chain if not found there
console.log(cos(0.5)) // 0.8775825618903728
}
}
foo();