eval会直接在调用函数内插入代码,篡改词法作用域:非严格模式下可声明变量遮蔽外部同名标识符,严格模式虽隔离作用域但仍存性能与调试缺陷,结合不可信输入更引发xss或拒绝服务风险。

eval 函数会直接在调用它的函数内部“插入”代码,让引擎误以为那段字符串本就写在那里——结果就是它能声明变量、覆盖同名标识符,从而篡改原本静态确定的词法作用域结构。
eval 在非严格模式下修改局部作用域
当 eval 执行含 var 声明的字符串时,会在当前函数作用域中创建新变量,遮蔽外部同名变量:
- 比如
function foo(a) { eval('var b = 3'); console.log(b); },b 就成了 foo 内部变量 - 若外部已有
var b = 2,foo 内部的console.log(b)输出的是 3,不是 2 - 这违背了“词法作用域由书写位置决定”的基本原则,运行时动态注入改变了作用域气泡
eval 引发变量遮蔽与查找失效
作用域查找从最内层开始,遇到第一个匹配就停止。eval 注入的变量会提前拦截查找路径:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 原意是访问全局
b,但 eval 声明了局部b,引擎就不再往外找 - 即使只读取不赋值,
console.log(a, b)中的b仍会取 eval 创建的那个 - 这种遮蔽不可逆,且对开发者隐蔽——代码里根本看不到那个
var b的声明
严格模式下行为不同但问题未根除
启用 "use strict" 后,eval 会建立独立作用域,不再污染外层:
-
function test(){ "use strict"; eval("var a = 1"); console.log(a); }会报错 ReferenceError - 看似安全,但 eval 内部仍无法被 JIT 编译优化,执行慢、调试难、压缩工具可能出错
- 若混用非严格/严格上下文,行为不一致,增加维护风险
真正危险的是动态拼接与执行不可信输入
eval 的破坏性在结合用户输入或远程数据时急剧放大:
-
eval(userInput)可能执行while(true){}导致页面卡死 - 更糟的是
eval('fetch("/api?token="+document.cookie)')等 XSS 载荷 - 即便加了过滤,字符串拼接逻辑也极易绕过,安全边界模糊
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










