ES6 变量的解构赋值
ES6允许按照一定的模式。从数组和对象中提取值,对变量进行赋值,这被称为解构。
一、数组解构赋值
<script> //以前的赋值 let a=1; let b=2; console.log(a);//1 console.log(b);//2 //ES6赋值,从数组中提取值,按照对应位置,对变量赋值 let [c,d]=[3,5]; console.log(c);//3 console.log(d);//5 </script>
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值,我们可以看看更多的例子
let [foo,[[bar],baz]]=[1,[[2],3]]; console.log(foo);//1 console.log(bar);//2 console.log(baz);//3 let [first,,third]=["aaa","bb","cc"]; console.log(first);//aaa console.log(third);//cc //将数组剩余部分赋值给一个变量。 let [head, ...tail] = [1, 2, 3, 4,5,6,7]; console.log(head);//1 console.log(tail);//[2, 3, 4, 5, 6, 7] let [x, y, ...z] = [1,,3,4]; console.log(x);//1 console.log(y);//undefined;解构不成功,值为undefined console.log(z);//[3,4]
以上是完全解构,下面代码是不完全解构,但可以成功解构
let [aa,bb]=[3,4,5]; console.log(aa);//3 console.log(bb);//4 let [a, [b], d] = [1, [2, 3], 4]; console.log(a);//1 console.log(b);//2 console.log(d);//4
注:如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。
let [foo] = 1; let [foo] = false; let [foo] = NaN; let [foo] = undefined; let [foo] = null; let [foo] = {};
//前面五个表达式转为对象以后不具备 Iterator 接口,最后一个表达式本身就不具备 Iterator 接口。
看到这可能有点懵,什么是Iterator 接口?我们可以去阮一峰老师《ECMAScript 6 入门》Iterator进行详解。当然后面我也会写一篇关于Iterator的笔记
默认值
为了防止从数组中取出一个值为undefined
的对象,可以在表达式左边的数组中为任意对象预设默认值。
let [a=5,b=7]=[1]; console.log(a);//1 console.log(b);//7 // 需要注意的是在es6内部使用的是严格相等来判断一个位置是否有值。只有当数组中的成员严格等于undefined 默认值才能生效。 // 如果默认值里是null,因为null不严格等于undefined 所有默认值也不会生效。
let [c=2]=[null];
console.log(c);//a=null
//默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。 function fn(){ return 2; }; let [d=fn()]=[1]; console.log(d);//1
//默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x = 1, y = x] = [];
console.log(x);
console.log(y);// x=1; y=1
let [a = 1, b = a] = [2];
console.log(a);//a=2
console.log(b);//b=2
let [c = 1, d = x] = [1, 2];
console.log(c);//c=1
console.log(d);//d=2
let [e = f, f = 1] = [];
console.log(f);//Cannot access 'f' before initialization
//报错原因:因为e用f做默认值时,f还没有声明。
二、对象的解构赋值
注:对象解构不需要位置和数组解构位置一致,只要保证解构的变量名和属性一致即可。
let {p,q}={p:42,q:true} console.log(p);//42 console.log(q);//true
let {aa,cc}={cc:4,aa:2};
console.log(aa,cc);//2 4
无声明赋值
let a,b; ({a,b}={a:1,b:2}); console.log(a);//1 console.log(b);//2
注:
赋值语句周围的圆括号 ( ... ) 在使用对象字面量无声明解构赋值时是必须的。
{a, b} = {a: 1, b: 2} 不是有效的独立语法,因为左边的 {a, b} 被认为是一个块而不是对象字面量。
然而,({a, b} = {a: 1, b: 2}) 是有效的,正如 var {a, b} = {a: 1, b: 2}
你的 ( ... ) 表达式之前需要有一个分号,否则它可能会被当成上一行中的函数执行
解构对象赋值默认值
let {dd=10,ss=3}={dd:4}; console.log(dd);//4 console.log(ss);//3
解构可以用于嵌套结构的对象
let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p, p: [x, { y }] } = obj; console.log(p);//["Hello", {y: "World"}] console.log(x);//Hello console.log(y);//World
字符串解构赋值
注:字符串被转换成了一个类似数组的对象。
let [a,b,c,d,e]='hello' console.log(a);//h console.log(b);//e console.log(c);//l console.log(d);//l console.log(e);//o
let {length : len} = 'hello';
console.log(len); // 5
函数的解构赋值
function add([x,y]){ return x+y; } console.log(add([1,2]));//3