一、数组的解构赋值
基本用法
当为多个变量赋值时,可以使用下面的方法:
// ES5
let a = 1;
let b = 2;
let c = 3;
// ES6数组解构
let [a, b, c] = [1, 2, 3];
解构赋值与剩余参数结合使用:
// ES6数组解构,与剩余参数结合使用
let [a, ...b] = [1, 2, 3, 4];
console.log(b); // [2, 3, 4]
更为复杂的数组解构赋值:
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3
二、对象的解构赋值
对象的解构赋值其实跟数组的解构赋值类似,例子如下:
let { bar, foo } = { foo: ‘aaa’, bar: ‘bbb’ };
console.log(foo); // “aaa”
console.log(bar); // “bbb”
细心的同学可能会发现,对象的解构竟然不用像数组那样位置要与数据一一对应,这就是对象解构与数组解构之间的不同之处。对象无需注重左右两侧属性的位置对应关系,只要左侧中出现的属性名与右侧对象中的属性对应上,那么就会赋值成功!其实上面的bar与foo 其实是 bar: bar, foo: foo缩写写成了bar,foo。
如果解构失败,那么就会为属性名对应的值赋值为undefined。
下面再来看一个稍微复杂一点的例子:
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc // Object {start: Object}
start // Object {line: 1, column: 5}
要注意需要赋值的是变量,loc对应的是一整个大的Object对象,第二个loc: { start }中loc只是指明需要赋值得start的对象名称,loc: { start: { line }}亦是如何理解,要充分理解到模板与变量,赋值给的是变量,而模板只是提供一个标识位置。
另外注意的是,解构赋值可以取到继承属性,不一定是对象自身的属性。
三、字符串的解构赋值
const […a] = ‘hello’;
console.log(a); // [‘h’,‘e’,‘l’,‘l’,‘o’]
其实字符串之所以可以解构赋值是因为字符串被转化成了一个类似于数组的对象,并且该对象除了字符串中的字符外,还存在一个length的字符串长度的属性:
const {0:A,1:B,2:C,3:D,4:E,length:len} = ‘hello’;
// A,B,C,D,E分别对应h,e,l,l,o len对应字符串长度5
四、数值和布尔值的解构赋值
至于数值和布尔值,如果进行解构赋值首先会把数值和布尔值转为对象,然后可以获取对象里许多自带的方法或者属性,例如toString、valueof等,例子如下:
// 数值解构
let {valueOf: val,toString: str} = 123;
console.log(val === Number.prototype.valueOf); // true
console.log(str === Number.prototype.toString);// true
//布尔值解构
let {valueOf: valboolean,toString: strboolean} = true;
console.log(valboolean === Boolean.prototype.valueOf);// true
console.log(strboolean === Boolean.prototype.toString);// true
至于undefined与null赋值解构,由于undefined与null无法转为对象,所以进行赋值解构会报错,也就是说,undefined与null不存在赋值解构。
五、函数参数的解构赋值
先来看一个简单的例子:
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
这个例子里面函数的参数是一个数组,当调用add([1, 2])时其实相当于进行了一次数组的解构赋值 [x, y] = [1, 2]
当函数参数的解构赋值使用到默认值时:
function move({x = 0, y = 0} = {}) {
return [x, y];
}
console.log(move({x: 3, y: 8})); // [3, 8]
console.log(move({x: 3})); // [3, 0]
console.log(move({})); // [0, 0]
console.log(move()); // [0, 0]
但是注意如下例子:
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
console.log(move({x: 3, y: 8})); // [3, 8]
console.log(move({x: 3})); // [3, undefined]
console.log(move({})); // [undefined, undefined]
console.log(move());// [0, 0]
这块代码与前面说到的例子很相似,但是{x, y} = { x: 0, y: 0 }这个仅仅在未传入对象的时候起作用,当传入{}空对象的时候,x与y找不到值,所以都为undefined。
注意:在解构赋值中,圆括号()的使用要十分小心,可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。即解构赋值对应的变量才可以使用圆括号括起来,模板不能使用圆括号。