信息发布→ 登录 注册 退出

JavaScript with语句是什么_为什么不推荐使用它

发布时间:2026-01-06

点击量:
with语句将对象临时添加到作用域链头部,使属性可直接访问,但因破坏词法作用域、阻碍编译优化、调试困难,ECMAScript 5严格模式下已被完全禁用,属已淘汰语法。

with 语句到底做了什么

with 是 JavaScript 中一个被废弃的语法结构,它允许你临时将某个对象添加到作用域链头部,使得该对象的属性可以像局部变量一样直接访问。

比如:

const obj = { x: 1, y: 2 };
with (obj) {
  console.log(x + y); // 不报错,x 和 y 被解析为 obj.x / obj.y
}

这看起来方便,但实际执行时,JS 引擎必须在每次读取 xy 时,先检查它们是否是 obj 的自有属性,再沿作用域链向上查找——这个过程无法在编译期确定,导致所有相关变量访问都失去优化可能。

为什么严格模式下直接禁用

ECMAScript 5 开始,with 在严格模式("use strict")中被完全禁止,尝试使用会抛出 SyntaxError: Strict mode code may not include a with statement

原因很实际:

  • 它让代码的词法作用域变得动态且不可静态分析
  • 引擎无法进行变量提升、内联、常量折叠等基本优化
  • 调试器难以准确定位变量来源,堆栈信息模糊
  • eval 类似,属于“破坏作用域透明性”的设计

常见误用场景和替代写法

过去有人用 with 简化 DOM 操作或配置对象嵌套访问,例如:

with (document.getElementById('form').elements) {
  username.value = '';
  password.value = '';
}

这种写法现在应改用解构或显式引用:

const form = document.getElementById('form');
const { username, password } = form.elements;
username.value = '';
password.value = '';

或者更安全地逐个获取:

const form = document.getElementById('form');
form.elements.username?.value = '';
form.elements.password?.value = '';

要点:

  • 永远不要依赖 with 来“省略前缀”
  • 对象属性访问明确优于隐式作用域注入
  • 现代工具链(如 ESLint)默认会报 no-with 错误

它还在哪些地方悄悄出现

虽然你不会主动写 with,但某些旧库或压缩后的代码(尤其是早期 Closure Compiler 输出)可能残留。另外,非严格模式下的浏览器控制台里仍可执行,但这不代表它安全。

真正容易被忽略的是:即使整个脚本没写 with,只要某处用了 eval 并传入含 with 的字符串,也会触发禁用逻辑或运行时错误——而这类间接调用极难排查。

所以不是“不推荐”,而是“已淘汰”。现在看到它,就当看见一段需要重构的遗留代码。

标签:# javascript  # word  # java  # js  # 浏览器  # 工具  #   # 作用域  # 为什么  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!