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''0false 属于有效值,不会触发默认值。

语法

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 结合剩余运算符 ...(剩余项收集)

...变量名 必须放在解构最后一位,用于收集数组中剩余所有元素,结果为新数组。

语法规则

  1. 剩余运算符只能出现一次;
  2. 必须位于解构参数末尾。

示例

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 数组解构规则

  1. 匹配依据:索引/位置,与变量名无关;
  2. 跳过元素:用 , 占位;
  3. 默认值:仅在元素为 undefined 或数组长度不足时生效;
  4. 剩余运算符 ...:只能放末尾,收集剩余元素为数组。

7.2 对象解构规则

  1. 匹配依据:属性名,与顺序无关;
  2. 重命名:原属性: 新变量
  3. 默认值:属性不存在/值为 undefined 时生效;
  4. 已声明变量解构:必须用 () 包裹;
  5. 剩余运算符 ...:收集剩余属性为新对象,仅可放末尾。

7.3 高频易错点

  1. 引用类型默认值:数组、对象作为默认值,必须用函数返回(如 props 中 default: () => []),防止多个实例共享同一引用地址;
  2. 函数参数不传参报错:解构对象参数务必加 = {} 兜底;
  3. 剩余运算符位置:数组/对象解构中,... 只能在最后一位;
  4. 区分有效值与 undefined0、''、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