eval在非严格模式下直接调用可修改函数局部变量,严格模式或间接调用时作用域隔离;现代开发应避免使用,推荐function构造函数或显式传参等安全替代方案。

eval 本身不能真正改变当前作用域的词法环境,它只能在调用时的执行上下文中“看似”访问或修改变量,但受严格模式、调用位置和作用域链限制。
eval 在非严格模式下可间接影响局部变量
当 eval 被直接调用(即不通过别名、不赋值给变量、不嵌套在函数内间接调用),且处于函数作用域中时,它会拥有对当前函数作用域的写入权限:
- 可以声明新的
var变量,这些变量会提升并存在于当前函数作用域 - 可以给已存在的局部变量赋值,效果等同于正常赋值
- 不能声明
let或const(语法错误),也不能用function声明提升到函数顶部(行为不一致,不推荐)
示例:
function test() {var a = 1;
eval("a = 2; var b = 3;");
console.log(a, b); // 2, 3
}
eval 在严格模式下完全隔离作用域
只要当前函数或全局环境启用了严格模式("use strict"),eval 就运行在独立的词法环境中:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 内部声明的
var不会泄漏到外层函数 - 对同名变量的赋值只作用于 eval 自身作用域,不影响外部
- 试图修改外层
let/const会报错(ReferenceError)
示例:
function test() {"use strict";let x = 10;
eval("x = 20; var y = 5;");
console.log(x); // 10(未变)
console.log(y); // ReferenceError: y is not defined
}
间接调用 eval 完全无法访问局部作用域
一旦 eval 被包裹(如赋值给变量、作为参数传入、用括号调用),它就退化为全局作用域执行:
- 所有声明都落在全局对象上(浏览器中是
window) - 无法读写调用点的任何局部变量
- 即使在非严格模式下也失去对函数作用域的访问能力
示例:
function test() {var z = "local";
var indirect = eval;
indirect("console.log(z)"); // ReferenceError: z is not defined
(0, eval)("z = 'global'"); // 写入全局 z
}
替代方案:避免依赖 eval 作用域副作用
因安全、性能和可维护性问题,现代开发应避免使用 eval。若需动态执行与作用域交互的代码,可考虑:
- 用
Function构造函数(作用域更明确,但仍是新函数,不共享外层变量) - 将数据显式传入(如封装成对象参数),再在字符串中操作该对象属性
- 用模板字符串 +
with(不推荐,已被废弃且禁用在严格模式) - 用 AST 解析或专用表达式引擎(如 mathjs、expr-eval)处理安全可控的计算逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










