我很好奇为什么会这样:
var c = {
d: function myFunc() {
console.log(this === window);
}
};
var a = {
b: function() {
console.log(this === a);
(0,c.d)();
c.d();
}
};
a.b();
控制台输出:
True
True
False
所以似乎(0, c.d)()
与c.d.call(window)
相同,但我似乎无法找到有关其原因或方法的工作原理。谁能解释一下?
答案 0 :(得分:21)
如果您编写用逗号(,
)分隔的多个表达式,那么将评估所有表达式,但最终会得到最后一个表达式的值:
var x = (1,2,3);
console.log(x); // this will log "3"
现在(0,c.d)
是一个表达式,它将返回函数c.d
,但现在c
不再是函数的this
。这意味着this
将指向全局对象(window
),或者在严格模式下保持未定义。您可以通过以下任何方式获得相同的效果:
var f = function(x) { return x; };
f(c.d)();
或者只是
var f = c.d;
f();
答案 1 :(得分:16)
表达式(0, myFunc)
仅相当于myFunc
。 comma operator采用多个表达式,对其进行评估,并返回最后一个表达式,因此(0, myFunc)
仅返回myFunc
。
现在,在b
方法中,this
等于a
,因为b
附加到a
。换句话说,b
可以调用a.b()
。但是,myFunc
未附加到a
(您无法通过myFunc
致电a.myFunc()
),因此在myFunc
中, this
不能是a
。实际上,调用myFunc
时不设置其this
,因此它默认为全局对象window
(或在严格模式下保持未定义),因此其this
等于window
。
您可能想知道(0, listeners[i])()
的重点是什么,然后,当他们刚刚写完listeners[i]()
时。考虑这个代码创建一个包含两个元素的数组,这两个元素都是:
var listeners = [
function () { alert(this); },
function () { alert(this); }
];
当您致电listeners[0]()
时,在listeners[0]
功能中,this
等于listeners
,因为0
已附加到listeners
,就像b
附加a
的方式一样。但是,当您按(0, listeners[0])()
调用该函数时,listeners[0]
与listeners
数组“解耦”。*由于解耦函数不再附加到任何内容,因此this
是全局对象window
。
*就像你写的那样:
var temp = listeners[0];
temp();