JavaScript with() 方法
最后修改于 2025 年 4 月 4 日
在本文中,我们将展示如何在 JavaScript 中使用 with
语句。with
语句为语句扩展作用域链。
with 语句
with
语句为代码块扩展作用域链。它允许您访问对象的属性,而无需重复对象引用。语法为:with (expression) statement
。
虽然它可以使代码更短,但在现代 JavaScript 中不建议使用 with
语句。它使代码更难以优化,并且可能导致令人困惑的作用域问题。在严格模式下,不允许使用 with
语句。
with
语句将给定的对象添加到作用域链的头部。当查找变量名时,JavaScript 首先检查此对象。如果未找到该属性,它将继续搜索正常的作用域链。
基本 with 示例
以下示例演示了 with
语句的基本用法。
const person = { firstName: 'John', lastName: 'Doe', age: 30 }; with (person) { console.log(firstName); // John console.log(lastName); // Doe console.log(age); // 30 }
我们创建一个 person 对象,并使用 with
来访问其属性。在代码块内,我们可以直接引用属性,而无需对象名称。首先在 person 对象中查找属性。
$ node main.js John Doe 30
with 语句和变量作用域
with
语句会影响变量查找,但不会改变作用域。
const settings = { color: 'blue' }; const color = 'red'; with (settings) { console.log(color); // blue (from settings) console.log(window.color); // red (global) } console.log(color); // red (global)
我们演示了 with
如何影响变量查找。在代码块内,color
指的是 settings 属性。在外部,它指的是全局变量。要访问内部的全局变量,我们使用 window.color
。
$ node main.js blue red red
with 语句和函数调用
with
代码块内的函数调用可能会产生意想不到的行为。
const utils = { log: function(message) { console.log('Utils:', message); } }; function log(message) { console.log('Global:', message); } with (utils) { log('Hello'); // Which log function is called? }
我们在 utils 对象和全局作用域中都有一个 log
函数。在 with
代码块内,JavaScript 首先检查 utils 对象是否有 log
。由于它存在于那里,因此调用该版本,而不是全局版本。
$ node main.js Utils: Hello
with 语句和赋值
with
代码块内的赋值可能模棱两可。
const config = { debug: false }; with (config) { debug = true; // Modifies config.debug verbose = true; // Creates global variable! } console.log(config.debug); // true console.log(config.verbose); // undefined console.log(verbose); // true (global)
我们展示了赋值在 with
代码块中的工作方式。如果属性存在于对象上,则对其进行修改。如果不是,则创建一个全局变量(在非严格模式下)。这种行为可能导致错误,这也是不鼓励使用 with
的原因之一。
$ node main.js true undefined true
嵌套 with 语句
可以嵌套多个 with
语句,内部语句优先。
const outer = { prop: 'outer' }; const inner = { prop: 'inner' }; with (outer) { console.log(prop); // outer with (inner) { console.log(prop); // inner } console.log(prop); // outer }
我们演示了嵌套的 with
语句。内部代码块的对象在属性查找时具有优先权。在内部代码块结束后,查找将恢复到使用外部对象。这表明 with
如何暂时影响作用域链。
$ node main.js outer inner outer
来源
在本文中,我们演示了如何在 JavaScript 中使用 with
语句。虽然它可以缩短代码,但由于潜在的作用域和性能问题,通常不建议使用它。
作者
列出 所有 JS 数组函数。