Reputation: 37177
Consider the following two JavaScript snippets:
var x = 2;
function f() {
var y = x;
eval('var x;');
return y;
}
vs.
var x = 2;
function f() {
var y = x;
var x;
return y;
}
The only difference is I've replaced eval('var x;');
with var x;
.
The first one returns 2
, but the second one returns undefined
. Why?
Upvotes: 3
Views: 589
Reputation: 25682
That's because when the interpreter is in scope of function it sets value undefined
to all variables which are declared inside it (with var
keyword prefixed). It's no matter where you've put the declaration, if there's a variable declaration inside a function the variable's value will be undefined
until you set it's value explicitly. In the first case you have eval('var x;')
which is still not evaluated when the value of y
is being set. That's why the value of y
is 2
, because the value of the variable x
in the upper scope is 2
.
The same will be here:
var x = 2;
function foo() {
var y = x;
console.log(y); //undefined
console.log(x); //undefined
var x = 3;
}
function bar() {
var y = x;
console.log(y); //2
}
var x = 2;
function foobar() {
console.log(x); //undefined
var x;
console.log(x); // undefined
x = 3;
var y = x;
console.log(y); //3
}
The eval is evaluated just as a regular expression.
Upvotes: 1
Reputation: 48761
Because with the second one, the var
is hoisted* to the beginning of the function, before any other statements are executed.
So its as though you code was this:
var x = 2;
function f() {
var x, y
y = x;
return y;
}
But with the first one, the var x
is part of the eval()
expression, so it doesn't have the opportunity to be hoisted* as in the second one.
*The term "hoisted" is not an official term. Its just a word that people use to describe the fact that declarations happen before any expressions are evaluated within the execution context. Function declarations are also hoisted.
Upvotes: 1
Reputation: 413720
Variable declarations are hoisted by the parser to the top of the lexical scope. In the second block of code, the way it's actually run is:
function f() {
var x, y;
y = x;
return y;
}
Function declarations are also hoisted. The net effect is that a variable declaration should be considered to always include the entire lexical scope in which it appears. If variable x
is declared with var
anywhere in a function, then every reference to x
in that function is to the local variable.
In your first example, the eval()
line is just a regular expression statement, so it's executed in order of its appearance in the function.
Upvotes: 5