eval和with都会动态改变作用域链,破坏词法作用域封闭性,导致变量查找不可预测、引擎无法优化、调试困难,并在严格模式下触发语法错误,同时引入xss等安全风险。

eval 和 with 都会动态改变作用域链,导致变量查找不可预测、代码难以静态分析,这是它们最核心的共同问题。
破坏作用域封闭性
两者都绕过词法作用域规则,在运行时临时插入对象到作用域链顶端:
- with 把传入对象作为新一层作用域,所有未声明变量先在此对象上查找,再向上回溯;
- eval(尤其非严格模式下)可声明变量、函数,直接修改当前执行上下文的变量对象,使作用域边界模糊。
阻碍引擎优化与调试
JavaScript 引擎依赖静态作用域做变量提升、内联、死代码消除等优化:
- 遇到 with 或 eval,引擎必须保守处理——禁用大部分优化,性能明显下降;
- 调试器无法准确映射变量来源,堆栈追踪中作用域信息丢失,报错位置与实际逻辑脱节。
触发严格模式语法错误
ES5 起,严格模式明确禁止二者:
- with 语句在严格模式下直接 SyntaxError;
- eval 在严格模式中不创建新绑定,且禁止通过它声明 var/func,否则报错或行为受限。
引入安全隐患
二者都可能被用于执行不可信字符串,且缺乏天然沙箱机制:
- eval 执行任意代码,若输入来自用户或网络,极易引发 XSS 或远程代码执行;
- with 虽不执行代码,但配合 eval 或模板拼接时,会放大属性访问的不确定性,间接助长注入风险。











