Calling function with window scope explanation (0, function(){})()
I am curious as to why this works:
var c = {
d: function myFunc() {
console.log(this === window);
}
};
var a = {
b: function() {
console.log(this === a);
(0,c.d)();
c.d();
}
};
a.b();
Console output:
True
True
False
So it seems to be that (0, c.d)()
is the same as c.d.call(window)
, but I cannot seem to find much about why or how this works. Can anyone explain?
From: Closure Compiler Issues
Fiddle: http://jsfiddle.net/wPWb4/2/
Solution 1:
If you write multiple expressions separated by a comma (,
), then all expressions will be evaluated, but you will end up with the value of the last expression:
var x = (1,2,3);
console.log(x); // this will log "3"
Now (0,c.d)
is an expression that will return the function c.d
, but now c
is not the this
of the function anymore. This means that this
will point to the global object (window
), or remain undefined in strict mode. You would get the same effect with any of these:
var f = function(x) { return x; };
f(c.d)();
Or just
var f = c.d;
f();
Solution 2:
The expression (0, myFunc)
is equivalent to just myFunc
. The comma operator takes multiple expressions, evaluate them, and returns the last expression, so (0, myFunc)
returns just myFunc
.
Now, in your b
method, this
is equal to a
because b
is attached to a
. In other words, b
can be called by a.b()
. However, myFunc
is not attached to a
(you can't call myFunc
by a.myFunc()
), so in myFunc
, this
can't be a
. In fact, myFunc
is called without setting its this
so it defaults to the global object window
(or remains undefined in strict mode), and therefore its this
is equal to window
.
You might be wondering what the point of the (0, listeners[i])()
is, then, when they could have just written listeners[i]()
. Consider this code that creates an array with two elements, both functions:
var listeners = [
function () { alert(this); },
function () { alert(this); }
];
When you call listeners[0]()
, then in the listeners[0]
function, this
is equal to listeners
, because 0
is attached to listeners
, just like how b
was attached to a
. However, when you call the function by (0, listeners[0])()
, listeners[0]
is "decoupled" from the listeners
array.* Since the decoupled function no longer is attached to anything, its this
is the global object window
.
*It's as if you wrote:
var temp = listeners[0];
temp();