eval已基本被弃用,因其无法隔离上下文、易致XSS与沙箱逃逸;替代方案包括:JSON.parse解析标准JSON、expr-eval处理安全表达式、白名单函数映射替代动态调用、Function构造器在可信环境下有限隔离。

直接用 eval() 执行字符串代码,在现代 JavaScript 开发中已基本被弃用。它无法真正隔离执行上下文,会继承并污染当前作用域,带来 XSS、沙箱逃逸、调试困难和性能损耗等多重风险。替代方案的核心思路是:**不执行任意代码,而是解析结构化输入、映射预定义行为、或限制执行边界**。
用 JSON.parse 替代“伪 JSON”解析
很多场景下所谓“需要 eval”,其实只是想把一段类似对象/数组的字符串转成 JS 值——比如后端返回了没加引号的 key 或带函数的配置。只要数据本身不含可执行逻辑,就该走数据协议而非代码执行。
- ✅ 正确做法:强制后端返回标准 JSON;前端用
JSON.parse(input)—— 安全、快、可静态分析 - ⚠️ 避免变体:
eval('(' + str + ')')、new Function('return ' + str)()等仍可能执行副作用,且不校验格式 - ? 若必须兼容非标格式(如 key 无引号),先用正则或语法感知工具清洗为合法 JSON,再 parse,而非跳过解析直奔 eval
用表达式解析器处理数学/逻辑计算
当需求明确限定为“算一个数”或“判一个布尔值”(如公式引擎、低代码条件判断),应选用专为表达式设计的解析库,而非开放整个 JS 引擎。
- 推荐
expr-eval:支持四则运算、括号、常用数学函数(sin,log),默认禁用变量访问与副作用调用 - 示例:
parser.evaluate('2 * (3 + sin(0))')返回6;而parser.evaluate('fetch("/")')直接抛SyntaxError - 可扩展:通过
parser.functions显式注册白名单函数,不开放this、globalThis或原型链
用配置驱动 + 函数映射替代动态调用
在事件响应、动作编排、低代码平台等场景,“根据字符串名触发行为”很常见。此时应将行为抽象为数据,执行时只查表调用,彻底切断字符串到代码的映射链。
立即学习“Java免费学习笔记(深入)”;
- 定义动作白名单:
["show_alert", "navigate_to", "set_form_value"] - 用户配置传入结构化对象:
{ type: "set_form_value", field: "email", value: "{{user.email}}" } - 执行层硬编码映射:
handlers[action.type]?.(action),不拼接、不反射、不 require - 模板插值用
String.replace(/{{([^}]+)}}/g, (_, key) => scope[key]),而非eval求值
Function 构造器(仅限可信环境下的有限隔离)
若确实需动态生成函数(如编译 DSL、构建运行时逻辑),new Function 比 eval 更可控:它默认在全局作用域执行,不访问闭包变量,且可配合严格模式限制。
- 示例:
const calc = new Function('a', 'b', '"use strict"; return a * b'); - 优势:V8 可对其 JIT 编译,支持缓存复用;错误堆栈清晰;无法读写外层
let/const - ⚠️ 注意:仍能访问
globalThis(如fetch,localStorage),不可用于处理不可信输入


















