Reputation: 8195
Why does this code:
function answer(x) {
function closure() {
var x = x || 42;
console.log(x);
}
closure();
}
foo();
always prints 42
?
The logic would be that something like foo(31337)
would print 31337
, since in closure
x
would be 31337
, so x || 42
would evaluate to 31337
. But this is not the case.
I just can't figure this out, so I'm posting this here in hope of receiving enlightenment from one of the true javascript gurus out there.
Upvotes: 1
Views: 111
Reputation: 169383
function answer(x) {
function closure() {
var x = x || 42;
console.log(x);
}
closure();
}
answer(20);
inside closure your defining x
as a local variable. This means it shadows the argument x
from the answer function higher up the chain. Since you declared x
with a var statement it defaults to undefined
.
Then x || 42
is undefined || 42
which is 42.
The issue here is that your using the same name. If you did x = x || 42
it would be x = 28 || 42
which sets x to 28.
The distinction is using the var
statement to create a new function local variable named x. Once you've done that, there is no way to reference variables of the same name that are higher up the scope chain.
To clarify how the interpreter works. Something like this :
function() {
var x = 52;
foo();
function foo() {
...
}
}
Gets converted into
function() {
function foo() {
}
var x;
x = 52;
foo();
}
Upvotes: 4
Reputation: 318488
var x
in var x = x || 42;
shadows the argument.
And since var ...
is always parsed at the beginning of the function - i.e. before the assignment is executed, the outer x is never available in there.
Here's a better example:
(function(x) {
(function() {
alert(x);
var x = 'inside';
})();
})(123);
The execution order is basically:
x
with value undefined
alert(x)
'inside'
to x
Upvotes: 3