用窗口范围说明调用函数(0,function(){})()

时间:2011-07-05 03:51:41

标签: javascript

我很好奇为什么会这样:

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)相同,但我似乎无法找到有关其原因或方法的工作原理。谁能解释一下?

来自:Closure Compiler Issues

小提琴:http://jsfiddle.net/wPWb4/2/

2 个答案:

答案 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)仅相当于myFunccomma 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();