解构赋值 - JavaScript

基本变量赋值

jsconst foo = ["one", "two", "three"];

const [red, yellow, green] = foo;

console.log(red); // "one"

console.log(yellow); // "two"

console.log(green); // "three"

解构的元素多于源元素

在从右侧赋值指定长度为N的数组进行数组解构时,如果左侧赋值指定的变量数量大于N,则仅为前N个变量赋值。其余变量的值将为 undefined。

jsconst 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

交换变量

两个变量的值可以在一个解构表达式中交换。

在没有解构赋值的情况下,交换两个值需要一个临时变量(或者,在某些低级语言中,XOR 交换技巧)。

jslet a = 1;

let b = 3;

[a, b] = [b, a];

console.log(a); // 3

console.log(b); // 1

const arr = [1, 2, 3];

[arr[2], arr[1]] = [arr[1], arr[2]];

console.log(arr); // [1, 3, 2]

解析从函数返回的数组

始终可以从函数返回数组。解构可以使处理数组返回值更简洁。

在此示例中,f()将其输出值[1, 2]作为输出,可以使用解构在一行中解析。

jsfunction f() {

return [1, 2];

}

const [a, b] = f();

console.log(a); // 1

console.log(b); // 2

忽略一些返回值

您可以忽略您不感兴趣的返回值

jsfunction f() {

return [1, 2, 3];

}

const [a, , b] = f();

console.log(a); // 1

console.log(b); // 3

const [c] = f();

console.log(c); // 1

您还可以忽略所有返回值

js[, ,] = f();

将绑定模式用作剩余属性

数组解构赋值的剩余属性可以是另一个数组或对象绑定模式。内部解构从收集剩余元素后创建的数组中进行解构,因此您无法以这种方式访问原始可迭代对象中的任何属性。

jsconst [a, b, ...{ length }] = [1, 2, 3];

console.log(a, b, length); // 1 2 1

jsconst [a, b, ...[c, d]] = [1, 2, 3, 4];

console.log(a, b, c, d); // 1 2 3 4

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

jsconst [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

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

jsconst { 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

从正则表达式匹配中解包值

当正则表达式exec()方法找到匹配项时,它会返回一个数组,其中首先包含字符串的整个匹配部分,然后包含与正则表达式中每个带括号的组匹配的字符串部分。解构赋值允许您轻松地将这些部分解包到数组中,如果不需要完整匹配,则可以忽略它。

jsfunction parseProtocol(url) {

const parsedURL = /^(\w+):\/\/([^/]+)\/(.*)$/.exec(url);

if (!parsedURL) {

return false;

}

console.log(parsedURL);

// ["https://mdn.org.cn/en-US/docs/Web/JavaScript",

// "https", "developer.mozilla.org", "en-US/docs/Web/JavaScript"]

const [, protocol, fullhost, fullpath] = parsedURL;

return protocol;

}

console.log(

parseProtocol("https://mdn.org.cn/en-US/docs/Web/JavaScript"),

);

// "https"

对任何可迭代对象使用数组解构

数组解构调用右侧的可迭代协议。因此,任何可迭代对象(不一定是数组)都可以被解构。

jsconst [a, b] = new Map([

[1, 2],

[3, 4],

]);

console.log(a, b); // [1, 2] [3, 4]

不可迭代对象不能作为数组解构。

jsconst obj = { 0: "a", 1: "b", length: 2 };

const [a, b] = obj;

// TypeError: obj is not iterable

可迭代对象仅迭代到所有绑定都分配为止。

jsconst obj = {

*[Symbol.iterator]() {

for (const v of [0, 1, 2, 3]) {

console.log(v);

yield v;

}

},

};

const [a, b] = obj; // Only logs 0 and 1

剩余绑定被急切地评估并创建一个新数组,而不是使用旧的可迭代对象。

jsconst obj = {

*[Symbol.iterator]() {

for (const v of [0, 1, 2, 3]) {

console.log(v);

yield v;

}

},

};

const [a, b, ...rest] = obj; // Logs 0 1 2 3

console.log(rest); // [2, 3] (an array)

Back to top: