with语句在非严格模式下可临时延长作用域链,使对象属性直接访问,但因破坏静态作用域、阻碍优化与调试,且严格模式禁用,现代开发已弃用,推荐解构赋值等更安全方式。

JavaScript 中可以通过 with 语句在非严格模式下临时延长作用域链,让指定对象的属性在语句块内直接访问,省去重复书写对象名。但要注意它已被现代开发实践普遍弃用,仅在理解历史机制或维护旧代码时需了解。
with 语句如何简化属性访问
with 会把传入的对象作为新的变量对象,插入到当前作用域链的最前端。之后在该语句块中,所有未声明的标识符会优先从这个对象上查找属性。
- 例如:
with (location) { console.log(href); }等价于console.log(location.href); - 只要
location对象有href、protocol、host等属性,就能直接使用这些名字,无需前缀 - 该效果仅限
with块内部,块外无法访问这些简写名
实际使用中的关键限制
这个特性受运行环境和语法模式严格约束,不是随时可用的工具:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ES5 严格模式下禁止使用
with,否则会直接报语法错误 - 现代浏览器和打包工具(如 Webpack、ESLint)默认启用严格模式,
with会被拒绝或警告 - IE8 及更早版本存在 bug:catch 块中的错误对象也会被注入作用域链,导致变量污染;IE9+ 已修复
- 代码可读性和调试难度上升——无法一眼判断某个变量是局部声明还是来自
with对象
更安全、更推荐的替代方式
与其依赖 with,不如用解构赋值或临时变量明确提取所需属性:
立即学习“Java免费学习笔记(深入)”;
- 解构:
const { href, protocol, host } = location;,之后直接用href、protocol - 临时变量:
const loc = location;,再写loc.href,语义清晰且无副作用 - 嵌套访问用可选链:
user?.profile?.settings?.theme,避免因中间项为null/undefined报错 - 高频访问某对象时,封装成辅助函数,比如
getURLParts()统一返回结构化信息
为什么现在基本不用了
with 的核心问题是破坏了静态作用域的可预测性。JavaScript 引擎无法在编译阶段确定变量绑定目标,导致无法有效优化、无法做静态检查、调试时作用域链混乱。加上它容易掩盖拼写错误(比如误写 hrf 不报错而是返回 undefined),长期来看风险远大于便利。

















