关于模块的雄辩的JavaScript章节.关于范围和评估函数

eloquent javascript chapter regarding modules. On scopes and eval function

本文关键字:范围 评估 函数 于范围 于模块 模块 JavaScript 章节      更新时间:2023-09-26

Eloquent javscript在模块章节的第10章中写道:

最明显的方法是特殊运算符 eval,它将执行 当前作用域中的代码字符串。这通常是一个坏主意 因为它破坏了正常作用域的一些理智属性 有,比如与外界隔绝。

这是代码:

function evalAndReturnX(code) {
  eval(code);
  return x;
}
console.log(evalAndReturnX("var x = 2"));
console.log(x)
console.log(code)

它输出:

2
ReferenceError: x is not defined (line 7)

这看起来很正常?什么给?我没有看到任何违反范围的行为?

Eval 有一些棘手的语义。从 mdn:

如果间接使用 eval 函数,则通过 除 eval 之外的引用,从 ECMAScript 5 开始,它适用于全局范围 而不是局部范围;这意味着,例如,函数 声明创建全局函数,并且代码 已评估无权访问范围内的局部变量 它被调用的地方。

因此,在您的情况下,由于您直接在该函数中调用eval,因此它定义了该函数的词法范围内的x,而全局范围不可用。但是,如果您要执行以下操作:

var _eval = eval;
function e() {
    _eval("var x = 2");
    return x;
}
console.log(e());
console.log(x);

它在这两种情况下都有效,因为这将在全局范围内定义x,该范围将由被调用方的词汇范围继承。

有关工作示例,请参阅此小提琴