在javascript中的eval内部声明

时间:2012-11-24 20:54:04

标签: javascript scope eval

考虑以下两个JavaScript代码段:

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;
}

唯一的区别是我已将eval('var x;');替换为var x;

第一个返回2,但第二个返回undefined。为什么呢?

3 个答案:

答案 0 :(得分:4)

解析器将变量声明提升到词法范围的顶部。在第二个代码块中,它实际运行的方式是:

function f() {
  var x, y;
  y = x;
  return y;
}

函数声明也会被提升。实际效果是变量声明应被视为始终包含它出现的整个词法范围。如果在函数中使用x 任何地方声明变量var,则该函数中对x的每次引用都是对局部变量。

在你的第一个例子中,eval()行只是一个正则表达式语句,因此它按照它在函数中出现的顺序执行。

答案 1 :(得分:1)

因为第二个,在执行任何其他语句之前,var被提升到函数的开头。

所以就好像你的代码就是这样:

var x = 2;
function f() {
    var x, y
    y = x;
    return y;
}

但是对于第一个,var xeval()表达式的一部分,因此它没有机会像第二个那样被提升*。


*“悬挂”一词不是官方用语。它只是人们用来描述声明在执行上下文中评估任何表达式之前发生的事实。函数声明也被悬挂。

答案 2 :(得分:1)

这是因为当解释器处于函数范围内时,它会将值undefined设置为在其中声明的所有变量(带有var关键字前缀)。无论你在何处放置声明,如果函数内部有变量声明,变量的值将为undefined,直到您明确设置它的值为止。在第一种情况下,当eval('var x;')的值被设置时,您仍然没有评估y。这就是y的值为2的原因,因为较高范围中变量x的值为2。 同样如下:

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
}

eval仅作为正则表达式进行评估。