我有这个代码:
var foo = {
x: 2,
bar: function() {
alert(this.x);
}
};
为什么foo.bar()
alert 2
while [foo.bar][0]()
alertsundefined
呢?
我有这个代码:
var foo = {
x: 2,
bar: function() {
alert(this.x);
}
};
为什么foo.bar()
alert 2
while [foo.bar][0]()
alertsundefined
呢?
所以,技术上[foo.bar][0]
等价于foo.bar
,但是在调用函数的时候bar
已经失去了与对象的“词法绑定” foo
,所以当你调用它时,JavaScript 实际上会执行以下操作:
foo.bar.call([foo.bar]);
一般来说,这个表达式:
XXX.yyy(args)
被解释为:
XXX.yyy.call(XXX, args);
在这种情况下XXX
是[foo.bar]
和.yyy
是[0]
。
要修复它,您需要foo
再次显式绑定:
[foo.bar][0].call(foo);
当你这样做时[foo.bar][0]()
,this
在bar
is[foo.bar]
中,数组而不是对象foo
。
只是想象方法名称是数字0
(尽管这是错误的语法)。
([foo.bar]).0(); // you see, `this` became the array object: [foo.bar]
并且[foo.bar].x
是undefined
。
这是因为您正在调用数组对象上的函数。“this”关键字等于数组。
[foo.bar][0]();
在 javascript 中,调用函数的上下文可能会有所不同。“this”关键字可以根据调用方式具有不同的值。如果在对象(包括数组)上调用函数,该语言将使“this”等于调用它的对象。另一方面,您可以将另一个对象的函数保存到另一个变量中并调用它。就像你这样做:
var test=[foo.bar][0];
test();`//here is alert "2"
上下文将是窗口。
研究 javascript 中的 call 和 apply 方法。这将使您了解“this”关键字的灵活性。对于来自其他语言的许多程序员来说,这是一个很困惑的地方,但是一旦理解了这个原则,就会有很多力量来自它。例如,JQuery 使用“call”和“apply”在触发事件的元素的上下文中调用事件的回调。
那是因为当您创建[foo.bar]
一个数组时,您将它与主对象(foo)隔离开来,并且在您的函数中发出警报this.x
并且在新创建的对象 [foo.bar]this
中未定义