Ismail Badawi
Ismail Badawi

Reputation: 37177

Declaration inside eval in javascript

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

Answers (3)

Minko Gechev
Minko Gechev

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

I Hate Lazy
I Hate Lazy

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

Pointy
Pointy

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

Related Questions