with语句不推荐使用,因其将对象临时插入作用域链顶端,导致变量查找顺序改变,易引发歧义、性能下降及严格模式报错;应改用显式访问、解构或方括号语法。

with 语句不推荐使用,它不会真正“扩展”作用域链,而是将指定对象临时置于作用域链顶端,导致变量查找顺序改变——但这种行为容易引发歧义、性能下降和严格模式下直接报错。
with 是如何影响变量查找的
当执行 with (obj) { ... } 时,JavaScript 引擎会把 obj 临时插入到当前执行环境的作用域链最前端。后续代码中对标识符的引用(如 x)会优先在 obj 上查找,再逐级向上(局部、外层函数、全局)查找。
- 如果
obj有属性x,就用它的值; - 如果
obj没有x,但外层函数定义了let x = 10,则取该变量; - 如果都找不到,才会抛出
ReferenceError(非严格模式下可能意外创建全局变量)。
为什么 with 语句危险且被弃用
它破坏了静态可分析性:你无法仅看代码就确定某个变量来自哪里,IDE、压缩工具、调试器都难以准确推断。
- 严格模式下,
with直接语法错误,无法运行; - 引擎无法对
with块内代码做有效优化(如变量提升、内联判断); - 容易掩盖拼写错误:比如本想写
user.name,却误写成name,而恰好有个同名局部变量或全局变量,逻辑就悄悄错了。
替代方案:清晰、安全、可维护
用显式对象访问或解构代替隐式作用域注入。
立即学习“Java免费学习笔记(深入)”;
- 直接写
obj.prop,语义明确,无歧义; - 需要多次访问同一对象属性时,用解构:
const { name, age, city } = user;; - 若需动态属性名,用方括号语法:
obj[key],配合类型检查或存在性判断更稳妥; - 封装为函数或方法,把对象作为参数传入,逻辑更内聚。
兼容性与现实建议
现代浏览器和构建工具(如 Babel、ESLint)默认禁用 with。ESLint 规则 no-with 会直接报错;TypeScript 不支持解析 with;所有新项目应完全避免。
- 遗留代码中遇到
with,优先重构为显式访问; - 不要为了“少打几个点”牺牲可读性和健壮性;
- 记住:作用域是静态的,
with只是制造了动态查找的假象,代价远大于便利。


















