一. 解构数组
无论数组,还是对象,本质上还是根据对象的key来进行解构的,数组的key实际上就是其索引值。
例如有一个数组[‘’,null,1,3,44,null,''22]
比如我们想要解构出第三项和第5项的值,
我们可以用诸如
const ['','',a,'',b] = arr
const [,,a,,b] = arr
其实,我们也可以用对象的形式去解构
const {2: a,4: b} = arr
这样会更简单清晰,且更不容易出错
二. 解构对象
假如,有一个对象,我们需要得到一个对象的某些属性值,我们通常会用诸如
let obj = {a: 1, b:2,c: 9,d: {f: 0}}
const {a,b,c} = obj
let obj2 = {a,b,c}
解构赋值之后还要新建变量赋值,稍显麻烦,假如想得到的属性参数只需要排除原有对象少数的属性,我们用这种形式
let obj = {a: 1, b:2,c: 9,d: {f: 0}}
const {d,...obj2} = obj
不过要注意的是obj2和obj是一层的深拷贝,假如改变多层的属性值,会相互影响
同样
let obj = {a: 1, b:2,c: 9,d: {f: 0}}
let {d,a} = obj
a = 9
d.f = 3
console.log(d,obj)
// { f: 3 } { a: 1, b: 2, c: 9, d: { f: 3 } }
- 基础数据类型值的改变不会相互影响,如果不希望基础数据类型解构后重新赋值,可以用const声明;
- 如果是引入类型,由于拷贝的是地址,所以const对限制值的改变不起作用,此时如果不想被相互影响,可以先深拷贝之后再使用。
三. 解构字符串
原来,字符串也是可以用类似解构数组的方法进行解构,
比如
const [a,b,c] = 'hello'
console.log(a,b,c) // h e l
结合数组应用:
// 获取姓氏
const arr = ['李同学','王同学'];
arr.forEach(([item])=> {
console.log(item,'item') // 李 王
})
四. 更改解构变量的值
- 解构变量的值为普通数据类型时
const obj = {name: 'sandy',age: 18,relative: {id: 19}};
let {relative,age} = obj;
age = 19
console.log(age === obj.age) // false
类似于
let a = 18;
let b = a;
b = 19;
console.log(a === b) // false
- 解构变量的值为复杂数据类型时
const obj = {name: 'sandy',age: 18,relative: {id: 19}};
let {relative,age} = obj;
relative.id = 22
console.log(relative === obj.relative) // true
const obj = {name: 'sandy',age: 18,relative: {id: 19}};
let {relative,age} = obj;
relative ={ id: 22}
console.log(relative === obj.relative) // false
普通数据类型拷贝的是具体的值,复杂数据类型拷贝的是地址,这点和平常的赋值是一致的。
但是在解构时容易被忽略,且可能出错。
五. 其他注意事项补充
- 关于解构默认值
ES6内部使用严格相等运算符( === )判断一个位置是否有值。所以,如果一个数组或对象成员不严格等于undefined,默认值是不会生效的。
let [x=1]= [null] // x 赋值为 null
let {y=1} = {y:null} // y 赋值为了 null
- 自带的length属性解构
其中,字符串和数组都有length属性
const {length} = [1,2,3] //length 赋值为了 3
const {length} = 'hello' // length 赋值为了 5
- 关于解构变量重命名
const { name } = {name: 'sandy',age: 18}
相当于
const { name: name } = {name: 'sandy',age: 18}
所以可以这样重命名
const { name: tempName } = {name: 'sandy',age: 18} // tempName赋值为了sandy,name为undefined
重命名之后name 成为了匹配的模式,tempName才是变量,所以真正被赋值的是变量tempName,而不是模式name
嵌套情况下的场景
const obj = {a: {b: {c: 233,d: 12}}}
我们如果想要获取a,b,d三个变量的值,可以这样解构
const {a,a: {b},a: {b: {d}}} = obj;