解构(Destructuring)
什么是解构?
使用ES6的一种语法规则,将一个对象或数组的某个属性提取到某个变量中
解构不会对被解构的目标造成任何影响
一、数组解构
如果解构不成功,变量的值就为undefined
等号右边的值只要具有Iterator接口,都可以采用数组形式的解构赋值。
1. 使用默认值
ES6内部使用严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。
let [x = 1] = [undefined];
// x = 1;
let [x = 1] = [null];
// x = null;
2. 嵌套解构
let [foo, [[bar], baz]] = [1, [[2], 3]];
// foo = 1
// bar = 2
// baz = 3
let arr = [1, 2, 3, {name: 'gyq'}];
let [,,,{name: oName}] = arr;
// oName = 'gyq'
3. 用对象来解构数组
数组本质上也是对象,因此可以对数组进行对象属性的解构
let arr = [1, 2, 3];
let {0: first, 2: last} = arr;
// first = 1 last = 3
let {legnth} = arr;
// length = 3
二、对象解构
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的。变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值。
1. 在解构中使用默认值
默认值生效的条件是,对象的属性值严格等于undefined
let {x = 3} = {};
// x = 3
2. 非同名属性解构
let {foo: baz} = {foo: 'gyq'}
// baz = 'gyq'
上面的代码,foo是匹配模式,baz才是变量,真正被赋值的是变量
实际上,对象的解构赋值是下面形式的简写:
let {foo: foo, bar: bar} = {foo: 'gyq', bar: 'gy'};
也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。
3. 默认值和非同名属性解构同时使用
let {foo: bar = 10} = {}
// bar = 10
4. 嵌套
const user = {
name: 'gyq',
age: 18,
sex: 'male',
address: {
province: 'jiangsu',
city: 'nanjing'
}
}
const {name, address: {province}} = user;
// name = 'gyq', province = 'jiangsu'
5. 特殊
如果要将一个已经声明的变量用于解构赋值,必须非常小心
// 错误写法
let x;
{x} = {x: 1};
// 上面的写法报错,因为JS引擎会将{x}理解为一个代码块,从而发生语法错误。
// 只有不将大括号写在行首,避免JS将其理解为代码块就可以。
// 正确的写法
let x;
({x} = {x: 1});
三、字符串、数值、boolean解构赋值
字符串、数值、boolean都可以进行解构
解构赋值的规则是,只要等号右边的值不是对象和数组,就先将其转为对象。由于undefined和null无法转为对象,所有对它们进行解构赋值时都会报错。
四、函数参数解构赋值
理解下面的两种不同,使用的时候也要注意:
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({{}}); // [0, 0]
move(); // [0, 0];
// 上面的代码,函数的参是是一个对象,通过对这个对象进行解构,得到变量x和y的值。
// 如果解构失败,x和y等于默认值。
function move({x, y} = {x: 0, y: 0}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined];
move({}); // [undefined, undefined];
move(); // [0, 0]
// 上面的代码是为函数的参数指定默认值,而不是为变量x和y指定默认值
五、用途
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取JSON数据
- 函数参数的默认值
- 遍历map结构
for (let [key, value] of map) { console.log(key + "is" + value); } - 输入模块的指定方法