数组的解构赋值
es6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称之为解构赋值。
在es5中
var a = 1,b = 2, c = 3;
在 es6中可以通过数组简写成:
let [a,b,c] = [1,2,3];
或者:
let [a,[b],c] = [1,[2],3];
只要按照对应的位置进行赋值,可以任意嵌套。
let [head, ...tail] = [1,2,3,4];
// head => 1, tail =>[2,3,4]
如果解构失败,变量的值就是undefined:
let [a,b] = [2];
//a => 2, b=>undefined
当 左边的变量数量个数小于右边的值的个数,是不完全解构,这种情况也是可以解构成功的,按照变量对应的位置进行解构即可。
let [a,b] = [1,2,3];
如果等号的右边不是数组(或者严格来说,不是可遍历的结构),那么将会报错。
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
以上都会报错:xxx is not iterable(…不是迭代器)
解构赋值对于var、let、const命令都适用。
**
解构赋值与默认值
**
let [a,b=2] = [1];//a = 1, b = 2
只有数组的值绝对等于undefined,才会被赋予默认值,否则即使是null和false也会被正常赋值。
(是否绝对等于undefined,不等于就走默认值,等于 就走右边附的值)
let [x=1] = [undefined]; // x = 1;
let [x=1] = [null]; // x = null;
如果把这个默认值给设置成了一个函数,即使我们在默认值那里执行了这个函数:
function f() {
console.log('aaa');
}
let [x = f()] = [1];
如果x被成功解构赋值了,没有赋值成默认值,那么这个函数就不会被执行,因为根本js根本不会走那里的代码,因此看上去执行了f函数,但是其实并没有,所以不会打印aaa的。
默认值可以引用解构赋值的其他变量,但是前提是该变量必须已经声明。
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] = []; // ReferenceError,因为x用到默认值y的时候,y还没有被声明
**
对象的解构赋值
**
var {a,b} = {a:123, b:'234'};
// a = 123;
// b = '234';
对象的解构赋值和数组的解构赋值的区别在于:数组的元素是按照次序排序的,因此它们赋值也是按照顺序赋值的,但是对象的属性是没有次序的,变量必须与属性同名,才会被赋值。
而与数组的解构赋值一样,如果我们的变量在对象中没有找到同名的属性的话,那么这个变量的值就是undefined。
对象的解构赋值的内部机制是:先找到同名的属性,然后把这个属性值赋予给对应的变量。
也就是说,这样的写法也是可以被赋值的:
{a:demo} = {a:123};
//demo 123
将a的属性值123拿出来赋值给变量a,但是变量a的值是demo,因此就是把demo的值变成了123。
注意这里demo才是真正的变量,a只是一个匹配模式,模式是不会被赋值的。
这样就完成了即使没有同名属性可以成功赋值的任务。
同时对象的解构赋值也只是可以有默认值的,条件和数组的一样。