javascript中eval内部的声明
考虑以下两个JavaScript片段:javascript中eval内部的声明,javascript,scope,eval,Javascript,Scope,Eval,考虑以下两个JavaScript片段: var x = 2; function f() { var y = x; eval('var x;'); return y; } vs 唯一的区别是我替换了eval('var x;')带有变量x 第一个返回2,但第二个返回undefined。为什么?语法分析器将变量声明提升到词法范围的顶部。在第二段代码中,它的实际运行方式是: function f() { var x, y; y = x; return y; } 功
var x = 2;
function f() {
var y = x;
eval('var x;');
return y;
}
vs
唯一的区别是我替换了eval('var x;')代码>带有变量x代码>
第一个返回2
,但第二个返回undefined
。为什么?语法分析器将变量声明提升到词法范围的顶部。在第二段代码中,它的实际运行方式是:
function f() {
var x, y;
y = x;
return y;
}
功能声明也被悬挂。最终的效果是,变量声明应该始终包含它出现的整个词法范围。如果变量x
在函数中的任意位置用var
声明,则该函数中对x
的每个引用都指向局部变量
在第一个示例中,eval()
行只是一个正则表达式语句,因此它是按其在函数中的出现顺序执行的。因为在第二个示例中,var
在执行任何其他语句之前被提升*到函数的开头
所以你的代码好像是这样的:
var x = 2;
function f() {
var x, y
y = x;
return y;
}
但是对于第一个表达式,var x
是eval()
表达式的一部分,因此它没有机会像第二个表达式那样被提升
*“吊装”一词不是官方术语。它只是一个人们用来描述这样一个事实的词,即声明发生在任何表达式在执行上下文中被计算之前。函数声明也会被挂起。这是因为当解释器在函数范围内时,它会将值未定义的
设置为它内部声明的所有变量(前缀为var
关键字)。无论您将声明放在何处,如果函数中有变量声明,则变量的值将未定义
,直到您显式设置它的值为止。在第一种情况下,您有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
}
eval作为正则表达式进行计算
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
}