If I do this:
var a = 0;
(function () {
var a = a; //want to make local a = global a
++a;
console.log("fn",a);
})();
console.log(a);
The output is:
fn NaN
0
Why does a
inside of the self executing function bee NaN
?
I know it works fine if I do:
(function () {
var b = a;
++b;
console.log("fn",b); // fn 1
})();
But if I go the way of the first version, it has the NaN
issue.
Why is this happening?
If I do this:
var a = 0;
(function () {
var a = a; //want to make local a = global a
++a;
console.log("fn",a);
})();
console.log(a);
The output is:
fn NaN
0
Why does a
inside of the self executing function bee NaN
?
I know it works fine if I do:
(function () {
var b = a;
++b;
console.log("fn",b); // fn 1
})();
But if I go the way of the first version, it has the NaN
issue.
Why is this happening?
Share Improve this question asked Jul 12, 2012 at 17:28 NaftaliNaftali 146k41 gold badges247 silver badges304 bronze badges 3-
i am not sure why it does that but i tried using
var a = window.a
and it behaves appropriately – Ibu Commented Jul 12, 2012 at 17:32 - @Ibu hmmm that is odd... – Naftali Commented Jul 12, 2012 at 17:33
- because all global variables are in window scope – jagm Commented Jul 12, 2012 at 17:36
4 Answers
Reset to default 12var a = a;
is actually var a; a = a;
due to variable hoisting. This means at the time of the assignment the old a
is already shadowed by the new one (which is undefined
).
The easiest way to avoid issues like that is passing the value as a parameter:
(function (a) {
++a;
console.log("fn",a);
})(a);
In case a
is a global variable you could also use var a = window.a;
like woz suggested - but since having global variables is usually a bad idea better stay with the parameters.
The a
variable inside your function expression shadows the a
variable declared on the outer scope.
It bees NaN
, since in the assignment:
var a = a;
The right-side a
it's actually referring to the a
in the local scope.
Variable declarations are done before the function actually starts to be executed, this is monly known as 'hoisting'.
Since it's the same variable, it holds the undefined
value, and when you try to add any number to this value, it bees NaN
:
console.log(undefined + 0);
In JavaScript, the current execution context (which includes things like variable scope) is established before your code begins executing.
What this means to you is that your local variable names are allocated first. Due to hoisting, labels from var
statements anywhere in the function are initialized to undefined in the current execution context. (Function statements are also initialized in this step.)
Next, your code actually begins executing. The a
label is already reserved in the current execution context, so var a = a;
simply assigns the local a
(which is undefined) to itself.
var a = window.a
works because you sidestep the scope issue by accessing global scope directly. However, this doesn't work in non-browser environments (like Node) because there is no window
; the global object in Node is global
.
there is a variable hoisting in javascript, so your code during execute looks like this:
(function () {
var a;
a = a; //want to make local a = global a
++a;
console.log("fn",a);
})();
so firstly you have local variable a as undefined and then you assign undefined to variable a