因为var能够重复声明,并且没法限制修改,也没有块级做用域,在一些时候不是很合适,因此出现了let和constjavascript
let [a,b,c] = [1,2,3] let [d,[[e],f]] = [1,[[2],3]]//d=1,e=2,f=3 let [x,y,...z] =['a'];//x="a",y=undefined,z=[] 结构不成功变量的值就为undefined
不彻底解构java
let [a,[b],c] = [1,[2,3],4];//a=1,b=2,c=4
对于set结构,可使用数组的解构数组node
let [x,y,z] = new Set(['a','b','c']);//a=a,y=b,z=c
主要数据结构具备Iterator接口,均可以采用数组形式的解构赋值,以下斐波那契数列的例子,利用generator函数es6
function* fibs(){ let a = 0 ; let b = 1; while(true){ yield a;//利用yield返回中间值 [a,b] = [b,a+b]; } } let [first,second,third,fourth,fifth,sixth] = fibs(); //first=0,second=1,third=1,fourth=2,fifth=3,sixth=5
默认值数组
解构赋值容许指定默认值,es6内部使用严格相等运算符===判断一个位置是否有值,因此只有当一个数组成员严格等于undefined,默认值才会生效;默认值能够引用解构赋值的其余变量,但该变量必须已经声明。数据结构
let [x,y='b'] = ['a'];//x='a',y='b' let [x=1] = [undefined];//x=1 let [x=1] = [null];//x=null let [x=1,y=x] = [2];//x=2,y=2 由于先把2解构赋给x,x把值赋给y,因此x,y都为2 let [x=1,y=x]=[1,2];//x=1,y=2
数组的解构和对象的解构有一个不一样,数组的元素按次序排列,变量的取值由其位置决定;而对象的属性没有次数,变量必需和属性同名,才能取得正确的值。函数
let {foo:foo,bar:bar} = {foo:'qqq',bar:'www'}//foo=qqq,bar=www //嵌套解构 let obj = {p:['hello',{y:'world'}]}; let {p:[x,{y}]} = obj//x=hello,y=world 此时p做为模式不会被赋值 let {p,p:[x,{y}]} = obj//p=['hello',{y:'world'}] 此时P做为变量赋值
如下实例进行了三次解构,分别是对loc,start,line三个属性,可是最后解构赋值时,只有line是属性,start和loc都是模式,而不是变量prototype
const node = { loc:{ start:{ line:1, column:5 } } }; //第一个参数是对loc进行解构,获得loc = { start: { line: 1, column: 5 } } //第二个参数对start进行解构,获得start = { line: 1, column: 5 } //第三个参数对line进行解构,获得 line = 1 let{ loc,loc:{start},loc:{start:{line}}} = node; console.log(loc);//{ start: { line: 1, column: 5 } } console.log(start); //{ line: 1, column: 5 } console.log(line);//1
嵌套赋值code
let obj = {}; let arr = []; ({foo:obj.prop, bar:arr[0]} = {foo:123,bar:true}); console.log(obj);//{prop:123} console.log(arr);//[true]
对象的默认值,和数组的默认值类似对象
var {x:y=3}={x:5}//y=5 var {x=3} = {x:undefined}//x=3 var {x=3} = {x:null}//x=null var {foo} = {bar:'bz}//foo=undefined解构失败变量的值等于undefined
一些错误写法:
let _tmp = {baz :'bz'}; _tmp.foo.baz;//报错,由于foo已是undefined,再取子属性会报错 let x; {x} = {x:1};//会报错,由于JavaScript引擎会把{x}解释成代码块,只有避免将大括号写在行首,避免将其解释成代码块,才能避免报错 let x; ({x} = {x:1});//正确写法
const [a,b,c,d,e] = 'hello'//a='h',b='e',.... let {length:len}='hello'//len=5
数值和布尔值的解构赋值
解构赋值时,若是等号右边是数值和布尔值,会先转为对象;而undefined和null没法转为对象,因此对它们解构赋值会报错
let {toString:s} = 123; console.log(s === Number.prototype.toString);//true let {toString:s} = true; console.log(s === Boolean.prototype.toString);//true let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
[[1, 2], [3, 4]].map(([a, b]) => a + b);//[3,7]
函数参数的解构可使用默认值,可是不一样的写法会有区别,有以下两种状况,一种是为函数的参数指定默认值,一种是为变量指定默认值
函数test的参数是一个对象,经过对对象的解构,获得参数x,y,解构失败,参数为默认值
function test({x=0,y=0} ={}){ return [x,y]; } console.log(test({x:2,y:5}));//[2,5] console.log(test({x:2}));//[2,0] console.log(test({}));//[0,0] console.log(test());//[0,0]
function test({x,y} = {x:0,y:0}){ return [x,y]; } console.log(test({x:2,y:5}));//[2,5] console.log(test({x:2}));//[ 2, undefined ] console.log(test({}));//[ undefined, undefined ] console.log(test());[0,0]