Reputation: 2555
Who can explain why result are [20, 20, 10, 10] in this code:
var x = 10;
var foo = {
x: 20,
bar: function () {
var x = 30;
return this.x;
}
};
console.log(
foo.bar(),
(foo.bar)(),
(foo.bar = foo.bar)(),
(foo.bar, foo.bar)()
);
Links to specification are welcomed
Upvotes: 8
Views: 1961
Reputation: 3446
Can't point you at specification, but i can highly recommend reading Douglas Crockford's "Javascript: The good parts". This book will help you understand most of the weird but great features of JavaScript.
As of your question:
this
keyword in bar
function is bound to foo
objectIn javascript you can assign variables from right to left multiple times
z = 3; x = (y = z); console.log(x); //3
functions are variables as anything else. So you are assigning the function foo.bar
to foo.bar
, but the parenthesis causes the assigned function to be returned, and then executed.
(foo.bar = foo.bar)();
//is the same as
var f = (foo.bar = foo.bar);
f();
//and this also the same as:
var f= foo.bar;
f();
The function returned from parenthesis is not bound to anything, so this
will refer to global object, in case of browsers - to the window
object.
4.. The clause (foo.bar, foo.bar)() is just alike:
a = (3, 4); //last value is returned, first just parsed.
//a contains 4
var f = (foo.bar, foo.bar);
//f contains body of foo.bar function,
f() // is executed in the context of `global` object, eg. `window`.
Please read about binding
of functions in JavaScript.
Upvotes: 7
Reputation: 37081
The first two function calls are equivalent. They are calling foo
's bar
method within the context of foo
– therefore the value returned by this.x
is the value of foo
's x
property, which is 20
.
The second two calls are both questionable/invalid syntax. Try running your code through JSLint and you'll that it spits out several errors and then chokes entirely. My best guess as to why they return 10
is that it's attempting to parse your code in a case where it really shouldn't and is getting confused. 10
might be returned because the browser cannot figure out what you're trying to do and is defaulting to global (window) scope where the value of x
is 10
. This would also explain Ramesh Vel's comment that the second two values appear as undefined
in IE. Due to the fact that the syntax is invalid, different implementations of JavaScript are likely to handle them differently.
Upvotes: 0