ECMAScript6 解构赋值

一、对象解构

用法

在一个赋值操作符左边放置一个对象字面量。

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
}

发表评论

您的电子邮箱地址不会被公开。