一、对象解构
用法
在一个赋值操作符左边放置一个对象字面量。
let { name, age } = { name: 'cherrie', age: '17' }
console.log(name, age) // cherrie 17
以上用了对象字面量属性简写的语法,换一种更加易于理解的写法。
let { 'name': name, 'age': age } = { 'name': 'cherrie', 'age': '17' }
console.log(name, age) // cherrie 17
换成与对象属性名不同的局部变量。
let { 'name': N, 'age': A } = { 'name': 'cherrie', 'age': '17' }
console.log(N, A) // cherrie 17
# 拆分
let N = ({ 'name': 'cherrie', 'age': '17' })['name']
let A = ({ 'name': 'cherrie', 'age': '17' })['age']
console.log(N, A) // cherrie 17
非初始化赋值
给已经声明过的变量赋值。
let name = 'mazey'
let age = '24'
// 开放的花括号视为代码块不会执行,需要加上括号;[(+-/ 开头时需要加上分号。
;({ name, age } = { name: 'cherrie', age: '17' })
console.log(name, age) // cherrie 17
解构表达式的值?
一段表达式都会有一个值返回,例如:
// 普通赋值
a = 123 // 123
b = 456 // 456
// 解构赋值
({ name, age } = { name: 'cherrie', age: '17' }) // { name: 'cherrie', age: '17' }
在函数的参数中使用解构赋值。
let person = { name: 'cherrie', age: '17' }
let name = 'mazey'
let age = '24'
function showPerson (p) {
console.log(p === person, p.name, p.age)
}
// 传入的实际上是 person
showPerson({ name, age } = person) // true "cherrie" "17"
// 且变量被重新赋值
console.log(name, age) // cherrie 17
默认值
倘若对应得属性名在 =
右边的字面量对象中不存在,则局部变量会被赋值为 undefined
,在变量名后面添加一个 =
即可赋予默认值。
let { name, age, gender = 'female' } = { name: 'cherrie', age: '17' }
console.log(name, age, gender) // cherrie 17 female
# 等于
let { name, age, gender: gender = 'female' } = { name: 'cherrie', age: '17' }
console.log(name, age, gender) // cherrie 17 female
# 等于
let { name, age, gender: gender = 'female' } = { name: 'cherrie', age: '17' , gender: undefined }
console.log(name, age, gender) // cherrie 17 female
二、数组解构
用法
数组解构相对简单一点,使用数组字面量即可,不像对象解构需要使用到键(key)值。
let [firstColor, secondColor] = ['red', 'blue']
console.log(firstColor, secondColor) // red blue
# 只取第二个值
let [, secondColor] = ['red', 'blue']
console.log(secondColor) // blue
使用数组解构替换两个变量的值
替换两个变量的值,常规做法需要增加一个临时变量暂存其中一个变量的值。
# 常规做法
let a = 123
let b = 456
let temp = a
a = b
b = temp
console.log(a, b) // 456 123
# 使用数组解构
let a = 123
let b = 456
;[a, b] = [b, a]
console.log(a, b) // 456 123
# 拆分
let a = 123
let b = 456
;[a, b] = [b, a] // ↓↓↓
;[a, b] = [456, 123] // = 右边先计算运行得到数组 [456, 123],然后赋值给左边的解构模式。
console.log(a, b) // 456 123
扩展运算符的应用
当数组的长度未知的时候,使用扩展运算符可以将剩余的值赋值给一个数组。
let [a, ...restColors] = ['red', 'blue', 'yellow']
console.log(a, restColors) // red ["blue", "yellow"]
使用扩展运算完成数组的深拷贝。
# 常规做法一
let arr1 = [1, 2, 3]
let arr2 = JSON.parse(JSON.stringify(arr1))
arr2.push(4)
console.log(arr1, arr2) // [1, 2, 3] [1, 2, 3, 4]
# 常规做法二
let arr1 = [1, 2, 3]
let arr2 = arr1.concat()
arr2.push(4)
console.log(arr1, arr2) // [1, 2, 3] [1, 2, 3, 4]
# 使用扩展运算符及数组解构
let arr1 = [1, 2, 3]
let [...arr2] = arr1
arr2.push(4)
console.log(arr1, arr2) // [1, 2, 3] [1, 2, 3, 4]
三、混合解构
混合使用对象解构和数组解构可以解析更复杂的数据格式,例如 Ajax 返回的 JSON。
const ajaxJSON = {
code: 0,
message: '成功',
data: {
list: [123, 456]
}
}
let { data: { list: [firstNum] } } = ajaxJSON
console.log(firstNum) // 123
四、疑问?
函数使用默认值的场景,经常看到在 =
后面重复添加一个与默认值相对应的字面量对象,这与 {}
有啥不同呢?
# 场景一
function foo ({ name = 'cherrie', age = '17' } = {}) {
// code
}
# 场景二
function foo ({ name = 'cherrie', age = '17' } = { name: 'cherrie', age: '17' }) {
// code
}