和 Python 类似,JavaScript 也支持结构赋值:
let names = ['Alice', 'Bob', 'Tiff', 'Light'];
let [name1, name2, name3, name4] = names;
console.log(name1, name2, name3, name4);
// Alice Bob Tiff Light
有时候这样做很方便,可以省去一些数组中间变量:
let [firstName, lastName] = "John Smith".split(" ");
console.log(firstName, lastName);
// John Smith
同样的,结构赋值可以省略部分元素:
let [a, , c] = [1, 2, 3];
console.log(a, c);
// 1 3
结构赋值不仅可以作用于数组,它可以作用于任何可迭代对象:
let [one, two, three] = new Set([1, 2, 3]);
console.log(one, two, three);
// 1 2 3
左侧也不局限于单个变量,可以是任意的可赋值的变量:
let userName = {};
[userName.firstName, userName.lastName] = "John Smith".split(" ");
console.log(userName.firstName, userName.lastName);
// John Smith
更常见的是结构赋值与迭代一起使用:
let user = { name: "John", age: 30 };
for (let [key, value] of Object.entries(user)) {
console.log(`${key}:${value}`);
}
// name:John
// age:30
遍历 Map 更为方便,因为 Map 本身就是个可迭代对象:
let userMap = new Map([["name", "John"], ["age", 30]]);
for (let [key, value] of userMap) {
console.log(`${key}:${value}`);
}
// name:John
// age:30
可以在结构赋值时使用...获取剩余部分的内容:
let [one2, two2, rest] = [1, 2, 3, 4, 5];
console.log(rest);
// [ 3, 4, 5 ]
如果缺少内容能够被结构赋值,结构赋值也不会报错:
let [firstName2, lastName2] = [];
console.log(firstName2, lastName2);
// undefined undefined
如果我们需要在这种情况下给结构赋值的结果赋予一个默认值:
let [firstName3, lastName3="Smith"] = "John".split(" ");
console.log(firstName3, lastName3);
// John Smith
对象解构赋值
let person = { name: "John", age: 30 };
let { name, age } = person;
console.log(name, age);
// John 30
左侧结构赋值的变量名需要与对象的属性名匹配,如果变量名与已经存在的变量名冲突,需要重新命名:
let { name: personName } = person;
console.log(personName);
// John
在对象结构赋值时,同样可以用...获取剩余部分:
let { name: personName3, personRest } = { name: "John", age: 30, city: "New York" };
console.log(personRest);
// { age: 30, city: 'New York' }
对象结构赋值同样可以指定默认值:
let options = { title: "Menu" }
let { height = 100, width = 200, title = "title" } = options;
console.log(height, width, title);
// 100 200 Menu
语法陷阱
如果不是在声明变量的同时进行结构赋值,就可能出现语法错误:
let userName2, userAge2;
{ name: userName2, age: userAge2 } = { name: "John", age: 30 };
// SyntaxError: Unexpected token '='
这里使用已有变量进行结构赋值,提示语法错误。
原因是在 JavaScript 中,{...}用于区分语法块,此时左侧的{ name: userName2, age: userAge2 }被认为是一个语法块,所以报错。
这种情况可以使用一个额外的(...)解决:
let userName2, userAge2;
({ name: userName2, age: userAge2 } = { name: "John", age: 30 });
console.log(userName2, userAge2);
// John 30
嵌套解构
对于复杂的对象,可以用嵌套结构进行结构赋值:
let person2 = {
name: "John",
age: 30,
skills: ["HTML", "CSS", "JS"],
address: {
city: "New York",
country: "USA"
},
};
let {
name: personName4,
age: personAge4,
skills: [skill1, skill2, skill3],
address: { city: personCity, country: personCountry },
} = person2;
console.log(personName4, personAge4, skill1, skill2, skill3, personCity, personCountry);
// John 30 HTML CSS JS New York USA
参数解构赋值
很常见的,我们会为函数参数指定默认值:
function setOption(height = 100, width = 200, title = "title"){
console.log(height, width, title);
}
但这对客户端程序不是很友好,比如为了使用默认值,就需要这样调用:
setOption(undefined, undefined, "Menu");
可以将函数参数定义为一个对象,并使用对象的结构赋值:
function setOption2({ height = 100, width = 200, title = "title" }){
console.log(height, width, title);
}
setOption2({width: 300});
// 100 300 title
但需要注意的是,这里函数必须要传递一个参数,因此如果完全使用默认值,也需要传递一个空对象:
setOption2({});
// 100 200 title
如果想避免这一点,可以:
function setOption3({ height = 100, width = 200, title = "title" } = {}){
console.log(height, width, title);
}
setOption3();
// 100 200 title
这样在传递空参数时,会默认指定一个空对象作为参数传递。
The End.
本文的完整示例代码可以从获取。

文章评论