解构赋值
info
解构赋值 是一种特殊的语法,可以将数组、对象、甚至任何可迭代对象“拆包”至一系列变量中。对可迭代对象使用解构赋值,其实是调用
for..of
并进行赋值的操作。解构赋值不会导致原来的数组或对象或可迭代对象自身被修改。
数组解构
tip
解构数组的完整语法:let [item1 = default, item2, ...rest] = array
,这表示数组的第一个元素被赋值给 item1
,第二个元素被赋值给 item2
,剩下的所有元素被复制到另一个数组 rest
。
// 以下两种写法是等价的
// let [firstName, surname] = arr;
let firstName = arr[0];
let surname = arr[1];
let [firstName, surname] = "John Smith".split(' ');
alert(firstName); // John
alert(surname); // Smith
可以通过添加额外的逗号来丢弃数组中不想要的元素
解构赋值等号左侧可以是任何“可以被赋值的”东西,比如一个对象的属性。
Object.entries(obj)
方法 可以与解构语法一同使用let user = {
name: "John",
age: 30
};
// 使用循环遍历键—值对
for (let [key, value] of Object.entries(user)) {
alert(`${key}:${value}`); // name:John, then age:30
}Map 可以与解构语法一同使用
let user = new Map();
user.set("name", "John");
user.set("age", "30");
// Map 是以 [key, value] 对的形式进行迭代的,非常便于解构
for (let [key, value] of user) {
alert(`${key}:${value}`); // name:John, then age:30
}使用解构赋值来交换两个变量的值是一个著名的技巧。
使用三个点 "..." 获取其余项
缺少对应值的变量都会被赋
undefined
解构赋值的变量可以声明默认值,默认值也可以是表达式、函数调用等。不过,这些表达式或函数只会在这个变量未被赋值的时候才会被计算。
// 默认值
let [name = "Guest", surname = "Anonymous"] = ["Julius"];
alert(name); // "Julius"(来自数组的值)
alert(surname); // "Anonymous"(默认值被使用了)// 使用了 prompt 函数来提供两个默认值,注意:prompt 将仅针对缺失值(surname)运行
let [name = prompt('name?'), surname = prompt('surname?')] = ["Julius"];
alert(name); // Julius(来自数组)
alert(surname); // 你输入的值
对象解构
tip
解构对象的完整语法:let {prop : varName = default, ...rest} = object
,这表示属性 prop
会被赋值给变量 varName
,如果没有这个属性的话,就会使用默认值 default
。没有对应映射的对象属性会被复制到 rest
对象。
对象解构赋值可以使用冒号来设置变量名称
{ sourceProperty: targetVariable }
解构赋值的变量可以声明默认值,默认值也可以是表达式、函数调用等。不过,这些表达式或函数只会在这个变量未被赋值的时候才会被计算。
let options = {
title: "Menu"
};
let {width = prompt("width?"), title = prompt("title?")} = options;
alert(title); // Menu
alert(width); // (prompt 的返回值)// 可以将冒号和等号结合起来
let options = {
title: "Menu"
};
let {width: w = 100, height: h = 200, title} = options;
alert(title); // Menu
alert(w); // 100
alert(h); // 200使用三个点 "..." 获取其余项
实时编辑器结果Loading...给已声明的变量解构赋值,需要把整个赋值表达式用括号包起来,否则会报错,报错原因是JavaScript引擎认为花括号是一个代码块。
let title, width, height;
{title, width, height} = {title: "Menu", width: 200, height: 100}; // 报错:SyntaxError: Unexpected token '='
嵌套解构
使用冒号设置变量名时进一步解构
智能函数参数
有时,一个函数有很多参数,其中大部分的参数都是可选的。如下:
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
// ...
}
问题是,在大部分的参数只需采用默认值的情况下,调用这个函数时会需要写大量的 undefined
,当我们处理更多参数的时候可读性会变得很差。
// 在采用默认值就可以的位置设置 undefined
showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])
可以用一个对象来传递所有参数,而函数负责把这个对象解构成各个参数:
想全部使用默认值的话,可以传入空对象:
可以通过指定空对象 {} 为整个参数对象的默认值来解决上述的报错: