People say Eval将动态范围带入JavaScript,但我看不出该语句是如何有效的。使用Eval使用与调用环境相同的词法环境/变量环境来评估表达式(引用ECMA 262 v. 5)。表达式的赋值或声明显然是动态的,但我不认为它引入动态范围是有效的。
我是否正确地说Eval没有引入动态范围?
答案 0 :(得分:1)
是和否。
严格意义上说,没有;该语言仍然以词汇方式运行(this
除外,它始终是动态范围的。)
但是,如果您阅读了与之关联的the whole question,则会看到提问者使用eval
来模拟动态范围。
var x = 1;
function g() {
print(x);
x = 2;
}
function f() {
// create a new local copy of `g` bound to the current scope
// explicitly assign it to a variable since functions can be unnamed
// place this code in the beginning of the function - manual hoisting
var g = eval(String(g));
var x = 3;
g();
}
f(); // prints 3
print(x); // prints 1
模拟动态范围完全可以通过该问题的提问者使用它来实现。提问者正在使用eval
将外部定义的函数实际导入另一个函数的范围。这需要对函数进行字符串化并重新声明它。因此,外部定义的函数实际上并不是在另一个函数的范围内运行(这个示例并非真正在严格意义上证明了动态范围),因为声明了一个全新的函数。话虽如此,提问者的意图是模仿动态范围,他正在用eval实现这一目标。