一、数组赋值(从数组中提取值,按照对应位置,对变量赋值)
1. 完全解构(变量与值数目相等)
let arr = [1, 2, 3]; let [a,b,c] = arr; console.log(a, b, c); // 1 2 3
2. 不完全解构(变量的数目小于值的数目)
let arr = [1, 2, 3, 4]; let [a,b,c] = arr; console.log(a, b, c); // 1 2 3
3. 解构不成功(变量的数目大于值的数目)
let arr = [1, 2]; let [a,b,c] = arr; console.log(a, b, c); // 1 2 undefined
备注:以上三种情况都可以给变量赋上值。
4. 默认值
默认值生效的条件是,变量严格等于undefined
。
let arr = [1, 2]; let [a,b,c = 3] = arr; console.log(a, b, c); // 1 2 3
let arr = [1, 2, undefined]; let [a,b,c = 3] = arr; console.log(a, b, c); // 1 2 3
let arr = [1, 2, null]; let [a,b,c = 3] = arr; console.log(a, b, c); // 1 2 null
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
function fun () { console.log(1); } let [x = fun()] = [1];
console.log(x); // 1
// fun不会执行
function fun () { console.log('hhhhhhhhhhh'); } let [x = fun()] = [undefined]; console.log(x); // hhhhhhhhhhh undefined
// fun会执行
5. 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [x = 1, y = x] = []; // x=1; y=1 let [x = 1, y = x] = [2]; // x=2; y=2 let [x = 1, y = x] = [1, 2]; // x=1; y=2 let [x = y, y = 1] = []; // y is not defined
二、对象的解构赋值(数组是按顺序,但是对象直接赋值需要按属性名来赋值)
1. 变量名即是属性名
let obj = { name: 'lqw', age: 23 }; let {name, age} = obj; console.log(name, age); // lqw 23
2. 变量名不是属性名
let obj = { name: 'lqw', age: 23 }; let {name:a, age:b} = obj; console.log(a, b); // lqw 23
其实对象的赋值是下面形式的简写(对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。)
let {name: a, age: b} = {name: 'lqw', age: 23}; console.log(a, b); // lqw 23
三、字符串解构赋值
let [a, b, c] = 'lqw'; console.log(a, b, c); // l q w
四、数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true
上面代码中,数值和布尔值的包装对象都有toString
属性,因此变量s
都能取到值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
五、函数参数的解构赋值
function add([x, y]){ return x + y; } add([1, 2]); // 3
参考链接:http://es6.ruanyifeng.com/#docs/destructuring