Skip to content

解构赋值基础

解构赋值是 ES6 中最实用的特性之一,它允许从数组或对象中提取值,按照对应位置或属性名赋值给变量。

🎯 为什么需要解构#

传统方式从对象中取值:

const user = { name: '张三', age: 25, city: '北京' }
// ES5 写法
var name = user.name
var age = user.age
var city = user.city
// ES6 解构
const { name, age, city } = user

代码简洁了很多,而且意图更清晰。

数组解构#

基本语法#

按位置匹配:

const [a, b, c] = [1, 2, 3]
console.log(a) // 1
console.log(b) // 2
console.log(c) // 3

跳过元素#

用逗号跳过不需要的元素:

const [first, , third] = [1, 2, 3]
console.log(first) // 1
console.log(third) // 3
// 只取第一个和最后一个
const arr = [1, 2, 3, 4, 5]
const [head, , , , tail] = arr
console.log(head, tail) // 1 5

剩余元素#

... 收集剩余元素:

const [first, ...rest] = [1, 2, 3, 4]
console.log(first) // 1
console.log(rest) // [2, 3, 4]
// 实用场景:分离头部和尾部
const [head, ...tail] = ['a', 'b', 'c']
console.log(head) // 'a'
console.log(tail) // ['b', 'c']

🔶 剩余元素必须是最后一个:

// const [...rest, last] = [1, 2, 3]; // SyntaxError

默认值#

解构失败时使用默认值:

const [a, b, c = 3] = [1, 2]
console.log(c) // 3
const [x = 1, y = 2] = [undefined, null]
console.log(x) // 1(undefined 触发默认值)
console.log(y) // null(null 不触发默认值)

默认值可以是表达式,惰性求值:

function getValue() {
console.log('计算默认值')
return 100
}
const [a = getValue()] = [1]
// 不会打印,因为 a 有值
const [b = getValue()] = []
// 打印 '计算默认值'

交换变量#

不需要临时变量:

let x = 1
let y = 2
;[x, y] = [y, x]
console.log(x, y) // 2 1
// 三个变量轮换
let a = 1,
b = 2,
c = 3
;[a, b, c] = [c, a, b]
console.log(a, b, c) // 3 1 2

对象解构#

基本语法#

按属性名匹配:

const { name, age } = { name: '张三', age: 25 }
console.log(name) // '张三'
console.log(age) // 25

顺序无关:

const { age, name } = { name: '张三', age: 25 }
console.log(name) // '张三'
console.log(age) // 25

重命名变量#

属性名和变量名可以不同:

const { name: username, age: userAge } = { name: '张三', age: 25 }
console.log(username) // '张三'
console.log(userAge) // 25
// console.log(name); // ReferenceError

语法是 { 属性名: 变量名 }(注意:属性名在前,变量名在后):

// 从 API 响应中提取并重命名
const response = {
data: { id: 1, user_name: '张三' },
}
const {
data: { id, user_name: userName },
} = response
console.log(id) // 1
console.log(userName) // '张三'

默认值#

const { name, age = 18 } = { name: '张三' }
console.log(age) // 18
// 重命名 + 默认值
const { name: username = '匿名', role = 'user' } = {}
console.log(username) // '匿名'
console.log(role) // 'user'

剩余属性#

const { a, ...rest } = { a: 1, b: 2, c: 3 }
console.log(a) // 1
console.log(rest) // { b: 2, c: 3 }
// 实用场景:排除某些属性
const user = { id: 1, name: '张三', password: '123456' }
const { password, ...safeUser } = user
console.log(safeUser) // { id: 1, name: '张三' }

解构的实际应用#

函数参数解构#

// 传统写法
function createUser(options) {
const name = options.name
const age = options.age || 18
const role = options.role || 'user'
// ...
}
// 解构写法
function createUser({ name, age = 18, role = 'user' }) {
console.log(name, age, role)
}
createUser({ name: '张三' }) // 张三 18 user

函数返回值解构#

function getPosition() {
return { x: 100, y: 200 }
}
const { x, y } = getPosition()
console.log(x, y) // 100 200
// 数组返回值
function getRange() {
return [0, 100]
}
const [min, max] = getRange()
console.log(min, max) // 0 100

模块导入#

// 解构导入
import { useState, useEffect } from 'react'
// 等价于
import React from 'react'
const { useState, useEffect } = React

遍历 Map#

const map = new Map([
['name', '张三'],
['age', 25],
])
for (const [key, value] of map) {
console.log(`${key}: ${value}`)
}
// name: 张三
// age: 25

处理 JSON 数据#

const response = {
status: 200,
data: {
users: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
],
total: 2,
},
}
const {
data: { users, total },
} = response
console.log(users) // [{ id: 1, name: '张三' }, ...]
console.log(total) // 2

常见陷阱#

🔶 已声明变量的对象解构#

let name,
age
// 错误写法
// { name, age } = { name: '张三', age: 25 }; // SyntaxError
// 正确写法:用括号包裹
;({ name, age } = { name: '张三', age: 25 })

因为 { 开头会被解析为代码块,需要括号告诉解析器这是表达式。

🔶 解构 null 和 undefined#

// const { name } = null; // TypeError
// const { name } = undefined; // TypeError
// 安全写法
const { name } = null || {}
console.log(name) // undefined

🔶 字符串解构#

字符串可以被当作数组解构:

const [a, b, c] = 'hello'
console.log(a, b, c) // h e l
// 也可以解构 length 属性
const { length } = 'hello'
console.log(length) // 5

🔶 数字和布尔值#

数字和布尔值会先转为对象:

const { toString: fn } = 123
console.log(fn === Number.prototype.toString) // true
const { valueOf } = true
console.log(valueOf === Boolean.prototype.valueOf) // true

小结#

类型语法匹配方式
数组解构[a, b] = arr按位置
对象解构{ a, b } = obj按属性名
重命名{ a: newA } = obj属性名:变量名
默认值{ a = 1 } = objundefined 时生效
剩余元素{ a, ...rest } = obj收集剩余部分

解构让代码更简洁、意图更清晰,是日常开发中使用频率最高的 ES6 特性之一。