严格模式下eval无法污染外层作用域:var声明仅限临时作用域,let/const限于eval内部块;禁止用eval/arguments作标识符;间接调用eval退至全局但不创建隐式变量;推荐用function构造器替代。

严格模式下,eval 的作用域污染已被系统性限制:它不再能向外层函数作用域注入变量或函数,所有在 eval 内部用 var 声明的变量,只在 eval 执行时的临时作用域内有效,不会提升到调用它的函数作用域中;而 let 和 const 更严格,仅限于 eval 字符串内部的块级作用域。这意味着——你不能再靠 eval("var x = 1") 来“悄悄”给函数加一个局部变量了。
严格模式自动切断 eval 变量泄露
非严格模式中,eval("var a = 1") 会让 a 成为外层函数的局部变量(甚至全局变量);但在严格模式下,这种声明完全失效——eval 运行在一个隔离的、嵌套的词法环境里,外层函数无法访问其中声明的 var 变量,也不会改变原有作用域链。
- 写
eval("var b = 2")后紧接着console.log(b)→ 报ReferenceError -
eval("let c = 3")或eval("const d = 4")中的c/d仅在该次eval字符串内部可读,执行完即销毁 - 即使
eval内部修改了外层已存在的变量(如eval("x = 10")),也仅限该变量原本就可被访问(即已声明),不会创建新绑定
禁止用 eval、arguments 当标识符
严格模式进一步堵住潜在入口:不允许把 eval 或 arguments 当作变量名、函数名或参数名。这防止了通过重定义它们来绕过限制或制造歧义。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
-
function test(eval) { }→SyntaxError -
const arguments = [];→SyntaxError -
function f(arguments) { }→SyntaxError
避免间接调用带来的意外行为
间接调用 eval(如 const e = eval; e("..."))在严格模式下会退回到全局作用域执行,但此时全局也不再是可写的 window(浏览器)或 globalThis(模块环境),且严格模式本身禁止隐式全局赋值,所以依然无法污染全局。
- 间接调用不会让
eval获得外层函数作用域,更不会挂变量到全局对象上 - 若尝试
e("x = 100"),因未声明x,直接抛ReferenceError(而非静默创建window.x) - 真正安全的做法是根本不用
eval;若必须动态执行,优先考虑Function构造器并明确传参
替代方案:更可控的动态执行
与其依赖 eval,不如用结构清晰、作用域明确的方式实现动态逻辑:
- 用
new Function(...args, body):每个调用都新建独立函数,变量完全隔离,不共享外层作用域 - 封装上下文执行函数,例如
evalWithContext('a + b', { a: 5, b: 3 }),用参数传递数据,避免字符串拼接和作用域混淆 - 对用户输入的表达式,先做语法校验(如白名单操作符、禁止分号/函数声明),再交由
Function安全求值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










