严格模式下eval拥有独立隔离作用域,不再共享调用者词法环境,其内部声明的变量和函数无法泄露到外部,且未声明变量赋值会抛出referenceerror;new function是更安全的替代方案。

严格模式下,eval 的执行上下文发生了本质性变化:它不再共享调用者的词法环境,而是拥有独立的、隔离的作用域。这意味着在 eval 内声明的变量和函数,无法泄露到外部作用域中——这是最核心的行为差异。
eval 不再污染调用者作用域
非严格模式下,eval("var x = 1") 会在当前函数或全局作用域中声明变量 x;而严格模式下,该变量仅存在于 eval 自身的临时作用域内,执行结束后即不可访问。
-
eval("let a = 1; function f() {}")后,a和f在外部一律undefined -
eval("x = 2")若x未在外部声明,会直接抛出ReferenceError(严格模式禁止隐式创建全局变量) -
eval("var y = 3")声明的y仍不可从外部读取,即使var本应提升,也受限于eval的独立作用域
无法通过 eval 动态扩展局部作用域
开发者曾误以为 eval 能像“内联代码”一样扩展当前函数的变量声明能力,但严格模式彻底切断了这种耦合。
- 函数内使用
let或const声明的变量,其块级作用域特性与eval的隔离作用叠加,进一步强化了封装性 -
eval("name = 'updated'")只有在外部已用var/let/const显式声明过name时才可赋值成功;否则报错 - 试图用
eval在函数内动态声明参数同名变量(如eval("arg = 42")),不会覆盖形参,也不影响实参绑定
全局 eval 与 window.eval 的区别依然存在
即使启用严格模式,eval 的调用方式仍决定其作用域归属:
- 直接调用
eval(...)—— 严格模式下走独立作用域逻辑 - 显式调用
window.eval(...)—— 绕过严格模式限制,在全局作用域执行(不推荐,破坏严格性) -
new Function(...)是更安全的替代方案,可显式传入所需变量,避免作用域混淆
为什么这样设计?
根本目的是提升代码可预测性和安全性:
- 防止模板拼接、配置解析等场景中意外覆盖局部变量,导致难以调试的副作用
- 阻断基于
eval的作用域注入攻击路径,让动态执行代码的行为边界更清晰 - 与模块化趋势一致:ES6 模块默认启用严格模式,
eval的隔离行为也契合模块作用域的封闭理念











