赋值 (=)

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

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

试一试

let x = 2;
const y = 3;

console.log(x);
// Expected output: 2

console.log((x = y + 1)); // 3 + 1
// Expected output: 4

console.log((x = x * y)); // 4 * 3
// Expected output: 12

语法

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® 2026 语言规范
# sec-assignment-operators

浏览器兼容性

另见