ES6 解构赋值
一、概念概述
1. 定义
解构赋值(Destructuring Assignment)是 ES6 新增语法,允许按照一定模式,从数组、对象、嵌套结构中提取值,并快速赋值给变量。
核心作用:简化数据提取代码,替代传统逐个取值写法,提升代码简洁度与可读性,广泛用于变量声明、函数参数、Vue/React 组件传参、接口数据处理等场景。
2. 分类
分为两大核心类型:数组解构、对象解构,延伸出嵌套解构、字符串解构、函数参数解构、剩余/扩展运算搭配解构等用法。
二、数组解构赋值
数组解构遵循顺序匹配规则:变量位置与数组元素索引一一对应,和变量名无关。
2.1 基础语法
语法格式
// 完整解构
const [变量1, 变量2, ...] = 原数组;
基础示例
// 原数组
const fruits = ['苹果', '香蕉', '橙子'];
// 传统写法
const f1 = fruits[0];
const f2 = fruits[1];
// ES6 数组解构
const [f1, f2] = fruits;
console.log(f1, f2); // 苹果 香蕉
2.2 按需解构 / 跳过元素
不需要的元素直接用逗号占位,跳过对应索引位置。
const arr = [10, 20, 30, 40];
// 只取第1、第3个元素,跳过第二个
const [a, , c] = arr;
console.log(a, c); // 10 30
// 只取最后一个元素
const [, , , d] = arr;
console.log(d); // 40
2.3 解构默认值
当数组对应位置元素为 undefined 或数组长度不足时,变量会使用预设默认值。
注意:
null、''、0、false属于有效值,不会触发默认值。
语法
const [变量1 = 默认值, 变量2 = 默认值] = 原数组;
示例
// 场景1:数组长度不足,触发默认值
const [x = 1, y = 2] = [100];
console.log(x, y); // 100 2
// 场景2:对应元素为 undefined,触发默认值
const [m = 5] = [undefined];
console.log(m); // 5
// 场景3:元素为 null/空字符串,不触发默认值
const [n = 10] = [null];
console.log(n); // null
2.4 嵌套数组解构
支持多层嵌套数组,按层级、顺序逐层拆解。
const nestedArr = [1, [2, 3], 4];
// 嵌套解构
const [a, [b, c], d] = nestedArr;
console.log(a, b, c, d); // 1 2 3 4
// 嵌套+跳过元素
const [, [, c]] = nestedArr;
console.log(c); // 3
2.5 结合剩余运算符 ...(剩余项收集)
...变量名 必须放在解构最后一位,用于收集数组中剩余所有元素,结果为新数组。
语法规则
- 剩余运算符只能出现一次;
- 必须位于解构参数末尾。
示例
const list = [1, 2, 3, 4, 5];
// 提取前两个,剩余全部收集到 rest
const [v1, v2, ...rest] = list;
console.log(v1, v2); // 1 2
console.log(rest); // [3,4,5]
// 只收集开头以外所有元素
const [...all] = list;
console.log(all); // [1,2,3,4,5]
2.6 经典应用:变量交换
无需临时变量,快速交换两个变量值
let num1 = 10;
let num2 = 20;
// 传统写法:需要中间变量
// let temp = num1; num1 = num2; num2 = temp;
// 解构交换
[num1, num2] = [num2, num1];
console.log(num1, num2); // 20 10
三、对象解构赋值
对象解构遵循属性名匹配规则:变量名必须和对象属性名一致,与顺序无关(对象无序)。
业务开发、组件传参、接口数据解析使用频率最高。
3.1 基础语法
语法格式
const { 属性名1, 属性名2 } = 原对象;
基础示例
const user = { name: "张三", age: 22, gender: "男" };
// 传统取值
const name = user.name;
const age = user.age;
// 对象解构
const { name, age } = user;
console.log(name, age); // 张三 22
3.2 解构重命名
当变量名和对象属性名冲突,或想自定义变量名时,使用 属性名: 新变量名 格式重命名。
语法
const { 原属性名: 新变量名 } = 原对象;
示例
const user = { name: "李四", age: 25 };
// name 重命名为 userName,age 重命名为 userAge
const { name: userName, age: userAge } = user;
console.log(userName); // 李四
console.log(userAge); // 25
// console.log(name); 报错:name 未定义
3.3 解构默认值
对象不存在该属性 或 属性值为 undefined 时,启用默认值;null/0/'' 等有效值不触发。
基础默认值
const user = { name: "王五" };
// gender 属性不存在,使用默认值 "未知"
const { name, gender = "未知" } = user;
console.log(name, gender); // 王五 未知
重命名 + 默认值(组合用法,高频)
const user = { name: "赵六" };
// 先重命名,再设置默认值
const { name: uname, age = 18 } = user;
console.log(uname, age); // 赵六 18
3.4 嵌套对象解构
针对多层嵌套的对象,逐层拆解属性,是处理复杂接口数据的核心用法。
示例
// 嵌套对象
const info = {
id: 1,
user: {
nickname: "前端开发者",
addr: "上海"
}
};
// 逐层解构
const { id, user: { nickname, addr } } = info;
console.log(id); // 1
console.log(nickname); // 前端开发者
console.log(addr); // 上海
嵌套 + 重命名 + 默认值
const info = { id: 2 };
const {
id,
user: { nickname: nick = "匿名", addr = "未知地址" } = {}
} = info;
console.log(nick, addr); // 匿名 未知地址
补充:
user = {}防止外层user属性不存在时,内层解构直接报错。
3.5 结合剩余运算符 ...
提取部分属性,剩余所有属性收集为新对象,常用于对象拷贝、剔除指定字段。
规则:剩余运算符必须放在解构最后一位。
const obj = { a: 1, b: 2, c: 3, d: 4 };
// 提取 a、b,剩余 c、d 存入 restObj
const { a, b, ...restObj } = obj;
console.log(a, b); // 1 2
console.log(restObj); // { c:3, d:4 }
3.6 空解构 / 已有变量重复解构
场景1:单独解构已有对象(无声明关键字)
如果变量已经提前声明,解构时不能加 let/const/var,且外层必须加圆括号 ()。
let name = "";
const user = { name: "小明" };
// 错误写法:{ name } = user; 语法解析异常
// 正确写法:外层包裹 ()
({ name } = user);
console.log(name); // 小明
四、其他类型解构
4.1 字符串解构
字符串会被转为类数组对象,可按数组规则解构,也可解构 length 属性。
const str = "hello";
// 按索引解构字符
const [s1, s2] = str;
console.log(s1, s2); // h e
// 解构 length 属性
const { length } = str;
console.log(length); // 5
4.2 数值 / 布尔值解构
会先转为包装对象,几乎无实际业务用途,了解即可。
const { toString } = 123;
console.log(toString); // 方法
五、函数参数解构(Vue/项目核心用法)
函数参数解构是解构赋值最常用的实战场景,专门用来简化对象/数组类型的入参取值。
5.1 普通对象参数解构
传统写法需要在函数内部逐层取值,解构直接在形参位置拆解。
// 原始写法
function getUserInfo(user) {
console.log(user.name, user.age);
}
// ES6 形参解构(推荐)
function getUserInfo({ name, age }) {
console.log(name, age);
}
// 调用
getUserInfo({ name: "小张", age: 20 }); // 小张 20
5.2 参数解构 + 默认值
场景1:属性默认值
// 给每个参数设置默认值
function fn({ name = "游客", age = 0 }) {
console.log(name, age);
}
fn({}); // 游客 0
场景2:整体参数默认值(防止不传参报错)
如果调用函数时不传任何参数,解构会针对 undefined 取值导致报错,需给整个参数设置默认空对象 = {}。
// 完整健壮写法:属性默认值 + 整体参数默认值
function fn({ name = "游客", age = 0 } = {}) {
console.log(name, age);
}
fn(); // 不传参,正常输出 游客 0
5.3 参数解构 + 重命名
function fn({ name: uname, age: uage = 18 }) {
console.log(uname, uage);
}
fn({ name: "小李" }); // 小李 18
5.4 数组类型参数解构
// 数组入参解构
function getArr([a, b, ...rest]) {
console.log(a, b, rest);
}
getArr([10, 20, 30, 40]); // 10 20 [30,40]
六、结合 Vue 场景实战
6.1 Vue2 / Vue3 选项式 API 隐含解构
props 接收父组件数据,本质就是对象解构的应用:
<script>
export default {
// 定义接收规则
props: {
msg: String,
list: {
type: Array,
default: () => []
}
},
created() {
// 内部取值:this.msg / this.list,等价于对象解构
const { msg, list } = this;
console.log(msg, list);
}
}
</script>
6.2 Vue3 <script setup> 显式解构
defineProps 返回一个对象,直接解构取值,是 Vue3 标准写法:
<script setup>
// 方式1:数组写法,解构取值
const props = defineProps(['msg', 'list']);
const { msg, list } = props;
// 方式2:对象写法(带类型/默认值)+ 解构
const { msg, list } = defineProps({
msg: String,
list: {
type: Array,
default: () => []
}
});
</script>
七、核心规则与易错点总结
7.1 数组解构规则
- 匹配依据:索引/位置,与变量名无关;
- 跳过元素:用
,占位; - 默认值:仅在元素为
undefined或数组长度不足时生效; - 剩余运算符
...:只能放末尾,收集剩余元素为数组。
7.2 对象解构规则
- 匹配依据:属性名,与顺序无关;
- 重命名:
原属性: 新变量; - 默认值:属性不存在/值为
undefined时生效; - 已声明变量解构:必须用
()包裹; - 剩余运算符
...:收集剩余属性为新对象,仅可放末尾。
7.3 高频易错点
- 引用类型默认值:数组、对象作为默认值,必须用函数返回(如 props 中
default: () => []),防止多个实例共享同一引用地址; - 函数参数不传参报错:解构对象参数务必加
= {}兜底; - 剩余运算符位置:数组/对象解构中,
...只能在最后一位; - 区分有效值与 undefined:
0、''、null、false不会触发默认值。
八、常用场景速查表
| 使用场景 | 推荐写法 |
|---|---|
| 简单数组取值 | const [a,b] = arr |
| 简单对象取值 | const {name,age} = obj |
| 对象属性重命名 | const {name:uname} = obj |
| 函数对象入参 | fn({name,age} = {}) |
| Vue3 setup 接收 props | const {msg,list} = defineProps(...) |
| 变量交换 | [a,b] = [b,a] |
| 剔除对象部分字段 | const {a,...rest} = obj |