赋值运算符 (=)

**赋值 (=)** 运算符用于将值赋给变量或属性。赋值表达式本身具有一个值,即被赋值的值。这允许将多个赋值链接起来,以便将单个值赋给多个变量。

试一试

语法

js
x = y

参数

x

有效的赋值目标,包括 标识符属性访问器。它也可以是 解构赋值模式

y

指定要分配给 x 的值的表达式。

返回值

y 的值。

异常

ReferenceError

如果在严格模式下分配给在作用域中未声明的标识符,则会抛出。

TypeError

如果在严格模式下分配给 不可修改的属性,则会抛出。

描述

赋值运算符与用作语法分隔符的等号 (=) 完全不同,后者包括

所有这些地方都接受 = 右侧的赋值表达式,因此,如果有多个等号链接在一起

js
const x = y = 5;

这等效于

js
const x = (y = 5);

这意味着 y 必须是一个预先存在的变量,而 x 是一个新声明的 const 变量。y 被分配了值 5,而 x 使用 y = 5 表达式的值进行初始化,该值也是 5。如果 y 不是预先存在的变量,则在 非严格模式 下会隐式创建全局变量 y,或者在严格模式下会抛出 ReferenceError。要在一个声明中声明两个变量,请使用

js
const x = 5,
  y = 5;

示例

简单赋值和链接

js
let x = 5;
let y = 10;
let z = 25;

x = y; // x is 10
x = y = z; // x, y and z are all 25

赋值表达式的值

赋值表达式本身计算为右侧的值,因此可以同时记录值并将其分配给变量。

js
let x;
console.log(x); // undefined
console.log(x = 2); // 2
console.log(x); // 2

未限定的标识符赋值

全局对象位于作用域链的顶部。在尝试将名称解析为值时,会搜索作用域链。这意味着全局对象上的属性从每个作用域都可以方便地看到,而无需使用 globalThis.window.global. 限定名称。

因为全局对象具有 String 属性 (Object.hasOwn(globalThis, "String")),所以可以使用以下代码

js
function foo() {
  String("s"); // The function `String` is globally available
}

因此,全局对象最终将被搜索未限定的标识符。不必键入 globalThis.String;只需键入未限定的 String 即可。为了使此功能在概念上更加一致,对未限定标识符的赋值将假定您希望在全局对象上创建具有该名称的属性(省略 globalThis.),如果作用域链中没有声明相同名称的变量。

js
foo = "f"; // In non-strict mode, assumes you want to create a property named `foo` on the global object
Object.hasOwn(globalThis, "foo"); // true

严格模式 下,在严格模式下对未限定标识符的赋值将导致 ReferenceError,以避免意外地在全局对象上创建属性。

请注意,上述含义是,与流行的错误信息相反,JavaScript 没有隐式或未声明的变量。它只是将全局对象与全局作用域混为一谈,并在创建属性时允许省略全局对象限定符。

带解构的赋值

的左侧也可以是赋值模式。这允许同时将多个变量分配给多个变量。

js
const result = /(a+)(b+)(c+)/.exec("aaabcc");
let a = "",
  b = "",
  c = "";
[, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"

有关更多信息,请参见 解构赋值

规范

规范
ECMAScript 语言规范
# sec-assignment-operators

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅