12

我有这个代码:

var foo = {
    x: 2,
    bar: function() {
        alert(this.x);
    }
};

为什么foo.bar()alert 2while [foo.bar][0]()alertsundefined呢?

4

4 回答 4

9

所以,技术上[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);
于 2013-01-31T06:51:59.863 回答
3

当你这样做时[foo.bar][0]()thisbaris[foo.bar]中,数组而不是对象foo

只是想象方法名称是数字0(尽管这是错误的语法)。

([foo.bar]).0(); // you see, `this` became the array object: [foo.bar]

并且[foo.bar].xundefined

于 2013-01-31T06:52:27.457 回答
1

这是因为您正在调用数组对象上的函数。“this”关键字等于数组。

[foo.bar][0](); 

在 javascript 中,调用函数的上下文可能会有所不同。“this”关键字可以根据调用方式具有不同的值。如果在对象(包括数组)上调用函数,该语言将使“this”等于调用它的对象。另一方面,您可以将另一个对象的函数保存到另一个变量中并调用它。就像你这样做:

var test=[foo.bar][0];
test();`//here is alert "2" 

上下文将是窗口。

研究 javascript 中的 call 和 apply 方法。这将使您了解“this”关键字的灵活性。对于来自其他语言的许多程序员来说,这是一个很困惑的地方,但是一旦理解了这个原则,就会有很多力量来自它。例如,JQuery 使用“call”和“apply”在触发事件的元素的上下文中调用事件的回调。

于 2013-01-31T07:24:57.167 回答
0

那是因为当您创建[foo.bar]一个数组时,您将它与主对象(foo)隔离开来,并且在您的函数中发出警报this.x并且在新创建的对象 [foo.bar]this中未定义

于 2013-01-31T06:51:09.030 回答