let {aa,bb}={aa:"111",bb:"222"};//aa="111",bb="222"
1、对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let {aa,bb,dd}={bb:"222",aa:"111",cc:"333"};//aa="111",bb="222",dd=undefined
2、如果解构失败,变量的值等于undefined
。
let {aa}={bb:"111"};//aa=undefined
3、对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
// 例一 let { log, sin, cos } = Math; // 例二 const { log } = console; log('hello') // hello
上面代码的例一将Math
对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。例二将console.log
赋值到log
变量。
4、如果想要变量名和属性名不一样,则可以写成下面那样
let {aa:a,bb:b,cc:c}={aa:"111",bb:"222"};//a="111",b="222",c=undefined,如果引用aa、bb或cc则会报错:error:aa(bb、cc) is not defined
------------------------------------------------------------------------------ let obj={aa:"111",bb:"222"}; let {aa:a,bb:b}=obj;//a="111",b="222"
这实际上说明,对象的解构赋值是下面形式的简写
let { aa: aa, bb: bb} = { aa: '111', bb: '222' };
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。
前者是匹配模式,后者是变量,真正被赋值的是后者,而不是前者,而前者的作用是找到对象相同名字的属性。
5、与数组一样,解构也可以用于嵌套结构的对象。
let obj={ p:[ "aaa",{bbb:"222"} ] }; let {p:[a,{bbb:b}]}=obj;//a="aaa",b="222"
p和bbb都是模式,不是变量,因此不会被赋值。如果想要p和bbb也赋值,则可以写成下面那样
let obj={ p:[ "aaa",{bbb:"222"} ] }; let {p,p:[a,{bbb,bbb:b}]}=obj;//a="aaa",b和bbb="222",p=["aaa",{bbb:"222"}]
6、嵌套赋值
let obj={}; let arr=[]; ({aa:obj.prop,bb:arr[0]}={aa:"111",bb:222});//obj={prop:"111"},arr=[222]
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
let {aa:{bb}}={aa:111};//bb=undefined let {cc:{dd}}={dd:111,ee:222};//报错,因为cc在对象中不存在并且又要取子属性dd
7、对象的解构赋值可以取到继承的属性
const obj1 = {}; const obj2 = { foo: "bar" }; Object.setPrototypeOf(obj1, obj2); const { foo } = obj1;//foo="bar"
上面代码中,对象obj1
的原型对象是obj2
。foo
属性不是obj1
自身的属性,而是继承自obj2
的属性,解构赋值可以取到这个属性。
8、默认值
let {a=1}={};//a=1 let {b,c=3}={b:2};//b=2,c=3 let {d:e=4}={};//e=4 let {f:g=5}={f:6};//g=6
默认值生效的条件是,对象的属性值严格等于undefined
。
let {a=3}={a:undefined};//a=3 let {a=3}={a:null};//a=null
9、将一个已经声明的变量用于解构赋值,必须非常小心
let x; {x} = {x: 1};//报错
上面代码的写法会报错,因为 JavaScript 引擎会将{x}
理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
// 正确的写法 let x; ({x} = {x: 1});
10、解构赋值允许等号左边的模式之中,不放置任何变量名(虽然毫无意义,但是语法是合法的,可以执行)。因此,可以写出非常古怪的赋值表达式
({} = [true, false]); ({} = 'abc'); ({} = []);
11、数组本质是特殊的对象,因此可以对数组进行对象属性的解构
let arr = [1, 2, 3]; let {0 : f, [arr.length - 1] : l} = arr;//f=1,l=3