解构赋值

js/destructuring_assignment2026-10-29 11:03:47

解构赋值 语法是一种 Javascript 表达式。可以将数组中的值或对象的属性取出,赋值给其他变量。

你可以使用解构赋值将对象字面量的属性绑定到变量。就像这样 let { bar } = foo。这会创建一个名为 bar 的变量,并且将 foo 对象中属性名与之相同的属性的值赋给它。

基本使用

解构赋值语句以声明关键字开始,赋值的左侧定义了要从原变量中取出哪些值。

解构可迭代对象:

const x = [1, 2, 3, 4, 5];
const [y, z] = x;
// 这创建了两个变量
// const y = x[0];
// const z = x[1];

任何可迭代对象(不一定是数组)都可以解构。

在从赋值语句右侧指定的长度为 N 的数组解构的数组中,如果赋值语句左侧指定的变量数量大于 N,则只有前 N 个变量被赋值。其余变量的值将是 undefined。

const foo = ["one", "two"];

const [red, yellow, green, blue] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // undefined
console.log(blue); //undefined

解构对象:

const obj = { a: 1, b: 2 };
const { a, b } = obj;
// 这创建了两个变量
// const a = obj.a;
// const b = obj.b;

解构对象时使用自定义名称:

const obj = { a: 1, b: 2 };
const { a, b: c } = obj;
// 这创建了两个变量
// const a = obj.a;
// const c = obj.b;
// 并没有创建 b

解构深层对象和数组:

const obj = { a: 1, b: { c: 2 } };
const {
  a,
  b: { c },
} = obj;
// 这创建了两个变量
// const a = obj.a;
// const c = obj.b.c;

绑定与赋值

对于对象和数组的解构,有两种解构模式:绑定模式 和 赋值模式,它们的区别是有无声明关键字。

绑定模式

在绑定模式中,模式以声明关键字(var、let 或 const)开始。然后,每个单独的属性必须绑定到一个变量或进一步解构。

const obj = { a: 1, b: { c: 2 } };
const {
  a,
  b: { c },
} = obj;
// Two variables are bound: `a` and `c`

所有变量共享相同的声明,因此,如果你希望某些变量可重新分配,而其他变量是只读的,则可能需要解构两次——一次使用 let,一次使用 const。

赋值模式

在赋值模式中,模式不以关键字开头。每个解构属性都被赋值给一个赋值目标——这个赋值目标可以事先用 var 或 let 声明,也可以是另一个对象的属性——一般来说,可以是任何可以出现在赋值表达式左侧的东西。

const numbers = [];
const obj = { a: 1, b: 2 };
({ a: numbers[0], b: numbers[1] } = obj);
// The properties `a` and `b` are assigned to properties of `numbers`

当使用对象字面量解构赋值而不带声明时,在赋值语句周围必须添加括号 (),否则行开头的 { 会被当作语句块解释而报错。

默认值

每个解构属性都可以有一个默认值。当属性不存在或值为 undefined 时,将使用默认值。如果属性的值为 null,则不使用默认值,而使用 null。

const [a = 1] = []; // a is 1
const { b = 2 } = { b: undefined }; // b is 2
const { c = 2 } = { c: null }; // c is null

赋值到新的变量名并提供默认值:

const { a: aa = 10, b: bb = 5 } = { a: 3 };

console.log(aa); // 3
console.log(bb); // 5

默认值可以是任何表达式。仅在必要时计算表达式的值。

const { b = console.log("hey") } = { b: 2 };
// Does not log anything, because `b` is defined and there's no need
// to evaluate the default value.

剩余属性

你可以使用剩余属性(...rest)结束解构模式。此模式会将对象或数组的所有剩余属性存储到新的对象或数组中。

const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(others); // { b: 2, c: 3 }

const [first, ...others2] = [1, 2, 3];
console.log(others2); // [2, 3]

剩余属性必须是模式中的最后一个,并且不能有尾随逗号。

数组解构赋值的剩余属性可以是另一个数组或对象绑定模式。这允许你同时提取数组的属性和索引。

const [a, b, ...{ pop, push }] = [1, 2];
console.log(a, b); // 1 2
console.log(pop, push); // [Function pop] [Function push]
const [a, b, ...[c, d]] = [1, 2, 3, 4];
console.log(a, b, c, d); // 1 2 3 4

这些绑定模式甚至可以嵌套,只要每个剩余属性都在列表的最后。

const [a, b, ...[c, d, ...[e, f]]] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c, d, e, f); // 1 2 3 4 5 6

另一方面,对象解构只能有一个标识符作为剩余属性。

const { a, ...{ b } } = { a: 1, b: 2 };
// SyntaxError: `...` must be followed by an identifier in declaration contexts

let a, b;
({ a, ...{ b } } = { a: 1, b: 2 });
// SyntaxError: `...` must be followed by an assignable reference in assignment contexts

类似语法

以下语法类似:

  • 解构赋值;
  • for...in 和 for...of 循环中的循环变量;
  • 函数参数;
  • catch 绑定变量。

参考

解构赋值
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

本页目录