人们说Eval 为 JavaScript 带来了动态范围,但我看不出这种说法是如何有效的。使用 Eval 使用与调用环境相同的词法环境/变量环境来评估表达式(参考ECMA 262 v. 5)。表达式的赋值或声明显然是动态的,但我认为说它引入了动态范围是不合理的。
我是否正确地说 Eval 没有引入动态范围?
人们说Eval 为 JavaScript 带来了动态范围,但我看不出这种说法是如何有效的。使用 Eval 使用与调用环境相同的词法环境/变量环境来评估表达式(参考ECMA 262 v. 5)。表达式的赋值或声明显然是动态的,但我认为说它引入了动态范围是不合理的。
我是否正确地说 Eval 没有引入动态范围?
是和不是。
严格来说,不;该语言仍然在词法上运行(除了相对于this
,它始终是动态范围的)。
但是,如果您阅读链接到的整个问题,您会看到提问者正在使用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 实现这一点。