我对javascript'这个'有疑问。我明白这个'这个'是指调用函数的对象。在示例1中,如果我们调用obj.bar(),为什么this.x = 4
var x = 4,
obj = {
x: 3,
bar: function() {
var x = 2;
setTimeout(function() {
var x = 1;
alert(this.x);
}, 1000);
}
};
obj.bar();
输出:4
在下面的代码中,为什么this.x = 3和1之后:
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
var go = foo.baz.bar;
alert(go());
alert(foo.baz.bar());
输出: 3,1
答案 0 :(得分:3)
this
。确定何时调用函数。
在setTimeout的情况下,一旦经过一定的时间,该功能就会被突然执行。没有上下文,因此浏览器在全局上下文中调用该函数。你碰巧声明了一个x=4
的全局变量,所以这就是this.x将会相同的。如果您使用严格模式(通过在脚本顶部添加"use strict";
),那么对于setTimeout情况,this
将是未定义的,您将收到错误。
当你调用go()
时,你有一个没有上下文的独立函数,所以它在全局上下文中再次被调用。这导致它使用你的全局x = 3。
当你致电foo.baz.bar()
时,你终于有了一个上下文。上下文为foo.baz
,因此this
引用的内容为this.x
,等同于foo.baz.x
,等于1。
答案 1 :(得分:3)
当您在最顶层声明变量时,您将在aging(&ps[1])
对象中创建一个全局变量。顶级关键字window
是指this
。
window
当您致电var x = 4; // same as `window.x = 4`;
console.log(x); // same as `console.log(this.x)`;
时,obj.bar()
关键字会引用this
内的obj
。但是在bar
里面你有一个不同的setTimeout
,它是指你传递给this
的回调的调用者。此调用者未指定setTimeout
的值,因此它只是成为this
对象。因此,在此代码中:
window
setTimeout(function() {
var x = 1;
alert(this.x);
}, 1000);
与this.x
相同,正如您在全局范围内定义的那样window.x
。
解决第二个例子,当你为一个变量分配一个函数时,你会失去该函数的来源上下文:
4
现在,当您通知var go = foo.baz.bar;
时,该调用中没有任何点,这意味着没有明确的对象访问权,这意味着没有隐式go()
。在这种情况下,您仍然可以使用this
:
this
call
您可以使用use strict避免许多这些问题。在严格模式下,// outputs `3` because `this` is `window`, and `window.x` is `3`
// as declared in the global scope
alert(go());
// Will output `2` because `this` is `foo`
alert(go.call(foo));
// Will output `1` because `this` is `foo.baz`
alert(go.call(foo.baz));
// Will output `1` because the implicit value of `this` is `foo.baz`
// since we have an explicit object access in this function call
alert(foo.baz.bar());
在未明确或隐式定义时将是未定义的,而不是默认为this
对象。