发布于 2026-01-06 3 阅读
0

你可能还不了解解构。

你可能还不了解解构。

ES6引入解构赋值已经有一段时间了,现在所有主流浏览器都支持它。它可以用于任何有效的赋值操作,例如变量赋值、函数参数赋值等等。我们先来了解一下解构赋值的基本概念。

在引入解构赋值之前,将数组或对象的值赋给单个变量的语法过于冗长。

const array = [1, 2, 3];
const obj = { x: 4, y: 5, z: 6 };

const a = array[0], b = array[1], c = array[2];
const x = obj.x, y = obj.y, z = obj.z

console.log(a, b, c); // 1 2 3
console.log(x, y, z); // 4 5 6
Enter fullscreen mode Exit fullscreen mode

在解构时代之前,我们就是这么做的。现在让我们用ES6的方式来做。

const array = [1, 2, 3];
const obj = { x: 4, y: 5, z: 6 };

const [ a, b, c ] = array;
const { x, y, z } = obj; 

console.log(a, b, c); // 1 2 3
console.log(x, y, z); // 4 5 6
Enter fullscreen mode Exit fullscreen mode

好多了。有了基本概念,我们来深入探讨一下。


对象属性赋值模式

让我们深入分析一下const { x, y, z } = obj前面代码片段中的语法。它实际上是 `.` 的简写形式const { x: x, y: y, z: z } = obj。如果匹配的属性名与要声明的变量名相同,则可以简化语法。这里我们省略了 `.`x:的一部分{ x: x, .. }

通常,赋值操作遵循target=source某种target: source模式,但在解构赋值中,source: target则遵循另一种模式。例如:

const obj = { x: 4, y: 5, z: 6 };
const { x: X, y: Y, z: Z } = obj;

console.log(X, Y, Z); // 4, 5, 6
Enter fullscreen mode Exit fullscreen mode

这里声明了名为 `is` 的变量X, Y, Z,并分别给它们赋值obj.x, obj.y, obj.z。因此,如果匹配的属性名与变量名相同,则可以使用简写形式。JS 引擎会为我们完成这些工作,而我们只需保持代码简洁即可。

稍后分配

如前所述,解构可以用于任何有效的赋值操作。这意味着声明变量时并非总是需要使用解构操作。对于已声明的变量,解构仅执行赋值操作,正如我们在其他变量赋值操作中所看到的。例如:

let a, b, c, x, y, z;

[a, b, c] = [1, 2, 3];
({x, y, z} = { x: 4, y: 5, z: 6 });

console.log(a, b, c, x, y, z); // 1 2 3 4 5 6
Enter fullscreen mode Exit fullscreen mode

我们需要将整个赋值表达式包装起来()以进行对象解构,否则{ .. }左侧将被视为代码块语句而不是对象。

赋值表达式不必只是变量标识符。任何有效的赋值表达式都是允许的。例如:

// Object assignment
const obj = {};
const computedProp = 'z';

[obj.a, obj.b, obj.c] = [1, 2, 3];
({ x: obj.x, y: obj.y, [computedProp]: obj[computedProp] } = { x: 4, y: 5, z: 6 });

console.log(obj.a, obj.b, obj.c); // 1 2 3
console.log(obj.x, obj.y, obj.z); // 4 5 6
Enter fullscreen mode Exit fullscreen mode
// Array assignment
let array = [];

({ x: array[0], y: array[1], z: array[2]  } = { x: 4, y: 5, z: 6 });

console.log(array); // [4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

还记得传统的“不使用临时变量交换两个变量”的问题吗?现在我们有了新的解决方案:

let x = 10, y = 20;

[y, x] = [x, y];

console.log(x, y); // 20 10
Enter fullscreen mode Exit fullscreen mode

重复作业

对象解构形式允许多次列出同一个源属性。例如:

const { a: X, a: Y } = { a: 1 };

console.log(X, Y); // 1 1
Enter fullscreen mode Exit fullscreen mode

显然,在数组解构中这是不可能的😒️。

连锁

任何解构赋值表达式的返回值都是源对象/数组。让我们看看这意味着什么:

let a, b, c, x, y, z;

console.log({x, y, z } = { x: 4, y: 5, z: 6 }); // { x: 4, y: 5, z: 6 }
console.log([a, b, c] = [1, 2, 3]); // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

通过将对象值作为完成项传递,您可以将解构赋值表达式链接在一起:

let a, b, c, x, y, z;

[a, b] = [c] = [1, 2, 3];
( {x} = {y,z} = {x: 4, y: 5, z: 6} );

console.log(a, b, c); // 1 2 1
console.log(x, y, z); // 4 5 6
Enter fullscreen mode Exit fullscreen mode

[a, b] = [c] = [1, 2, 3]&( {x} = {y,z} = {x: 4, y: 5, z: 6} )从右向左求值(即,的返回值[c] = [1, 2, 3]被赋给[a, b],类似地,的返回值{y,z} = {x: 4, y: 5, z: 6}被赋给{x})。

可选作业

在解构赋值中,你不必将源对象/数组中存在的所有值都赋给变量。例如:

const [,,c] = [1, 2, 3];
const { y } = { x: 4, y: 5, z: 6 };

console.log(c, y); // 3 5 
Enter fullscreen mode Exit fullscreen mode

您可以跳过当前作用域中不需要的值。

采集

您可以在解构赋值中使用剩余元素语法,将值收集到单个变量中。例如:

const [a, ...b] = [1, 2, 3];
const { x, ...y } = { x: 4, y: 5, z: 6 };

console.log(a, b); // 1 [2, 3]
console.log(x, y); // 4 { y: 5, z: 6 }
Enter fullscreen mode Exit fullscreen mode

它的行为与函数的剩余参数类似

默认值赋值

在对象和数组的解构赋值中,您都可以为赋值语句提供默认值。例如:

const { w = 7, x = 8, y, z } = { x: 4, y: 5, z: 6 };
const [ a = 9, b, c, d = 10 ] = [1, 2, 3];

console.log(w, x, y, z); // 7 4 5 6
console.log(a, b, c, d); // 1 2 3 10
Enter fullscreen mode Exit fullscreen mode

对于源数组/对象中缺失的值,将应用默认值。这类似于默认函数参数

您可以将默认变量赋值与替代赋值表达式语法结合使用。例如:

const { w: WW = 10, x, y, z } = { x: 4, y: 5, z: 6 };

console.log(WW, x, y, z); // 10 4 5 6
Enter fullscreen mode Exit fullscreen mode

嵌套解构

如果要解构的值包含嵌套对象或数组,也可以解构这些值:

const array = [ 1, [2, 3, 4], 5 ];

const obj = { 
  x: {
    y: {
      z: 6
    }   
  }
}

const [ a, [ b, c, d ], e ] = array;

const { 
  x: { 
    y: { 
      z: w 
    } 
  } 
} = obj;

console.log(a, b, c, d, e); // 1 2 3 4 5
consoel.log(x); // {y: {z: 6}}
console.log(y) // {z: 6}
console.log(w); // 6
Enter fullscreen mode Exit fullscreen mode

解构参数

以上所有规则同样适用于函数参数的解构,因为在底层,参数会被赋值给实参。例如:

function baz([x, y]) {
  console.log(x, y);
}

baz([1, 2]); // 1 2
baz([1]); // 1 undefined
baz([, 2]); // undefined 2
Enter fullscreen mode Exit fullscreen mode

来源
[1]:《你不知道的JS:ES6及以后》,作者:Kyle Simpson

文章来源:https://dev.to/mpratapdev/you-may-not-know-destructuring-yet-2ce1