对象解构:
与数组的差异:
- 数组的元素是按次序排列的,变量的取值由它的位置决定;
- 对象的属性是没有次序的,变量必须与属性同名才能取到正确的值。
let { bar, foo } = { foo: 'aaa', bar: 'bbb' }
console.log(bar);//bbb
console.log(foo);//aaa
let { baz } = { foo: 'aaa', bar: 'bbb' }
console.log(baz);//undefined
// 如果说变量名和属性名不一致需要下面书写方法
let { foo: baz1 } = { foo: 'aaa', bar: 'bbb' }
console.log(baz1);//aaa
对象解构的内部机制:
- 先找到同名属性,然后再赋值未对应的变量
- 真正被赋值的是后者,而不是前者
let { foo11: foo1, bar11: bar1 } = { foo: 'aaa', bar: 'bbb' }
console.log(foo1);//aaa
console.log(bar1);//bbb
// console.log(foo11);//ReferenceError: foo11 is not defined :foo11是匹配的模式,foo1才是变量,真正被赋值的是变量foo1
嵌套结构的解构:
let obj = {
p: [
'Hello', {
y: 'World'
}
]
}
- 下面这是p是模式,不是变量,不会被赋值。
let { p: [x, { y }] } = obj
console.log(x);//Hello
console.log(y);//World
- 如果要给p赋值需要写成这样
let { p, p: [x, { y }] } = obj
console.log(x);//Hello
console.log(y);//World
console.log(p);//[ 'Hello', { y: 'World' } ]
默认值:
var { x1 = 3 } = {}
console.log(x1);//3
var { x2, y2 = 5 } = { x2: 1 }
console.log(x2);//1
console.log(y2);//5
var { x3: y3 = 3 } = {}
console.log(y3);//3
var { x4: y4 = 3 } = { x4: 5 }
console.log(y4);//5
- 默认值生效的条件是:对象的属性值严格等于undefined
var { x5 = 3 } = { x5: undefined }
console.log(x5);//3
var { x6 = 3 } = { x6: null }
console.log(x6);//null
解构失败:
let { foo2 } = { bar: 'baz' }
console.log(foo2);//undefined
- 如果解构模式是嵌套的对象,而子对象所在的父属性不存在,那么将会报错
let { foo4: { bar4 } } = { baz4: 'baz' }
//TypeError: Cannot read properties of undefined (reading 'bar4')
let _tmp = { baz5: 'baz5' }
console.log(_tmp.foo.bar);
// TypeError: Cannot read properties of undefined (reading 'bar')
注意:
如果将一个已经声明的变量用于解构赋值,必须非常小心
let x7;
{x7} = {x7:1}//SyntaxError: Unexpected token '='
// 正确的写法
({ x7 } = { x7: 1 })
console.log(x7);//1
补充:
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3]
let { 0: first, [arr.length - 1]: last } = arr//方括号这种写法属于:属性名表达式
console.log(first, last);//1 3