ES6解构赋值
解构赋值是什么
认识解构赋值
// 下标获取数组const arr = [1, 2, 3];const a = arr[0];const b = arr[1];const c = arr[2];console.log(a);console.log(b);console.log(c);//解构赋值const [a, b, c] = [1, 2, 3];console.log(a, b, c);什么是解构赋值:解析某一数据结构,将我们想要的的东西提取出来,赋值给变量或
数组解构赋值的原理
模式(结构)匹配
const [a, b, c] = [a,b,c];console.log(a, b, c);等价于“按位置匹配数组元素”:第 0 位 → a;第 1 位 → b;第 2 位 → c;底层逻辑是:左边是“结构模板”,右边是“数据源”
索引值相同的完成赋值
const [a, [, , b], c] = [1, [2, 4, 5], 3];console.log(a, c, b);//1,3,5 不取的,可以直接用逗号跳过先求值右侧表达式
function getArr() { console.log('getArr 被调用'); return [10, 20, 30];}const [a, b, c] = getArr();console.log(a, b, c);数组解构赋值的默认值
数组解构赋值的默认值机制,本质是:当“取到的值是 undefined 时”,才使用默认值,注意:不是 null,也不是“没有值”,而是 严格 === undefined
//基本用法const [a = 10, b = 20] = [];console.log(a, b);
//正常有值时,不使用默认值const [a = 10, b = 20] = [1];console.log(a); // 1console.log(b); // 20
//只有 undefined 才触发默认值,重点const [a = 10] = [null];console.log(a); // null ❗不是 10
//位置缺失才会触发默认值const [a = 10, b = 20, c = 30] = [1, undefined];console.log(a); // 1console.log(b); // 20console.log(c); // 30
//默认值可以是表达式(惰性执行)function getValue() { console.log("执行了 getValue"); return 99;}const [a = getValue()] = [];console.log(a);
//默认值不会重复执行(只在需要时执行)const [a = getValue()] = [1];console.log(a);//不会打印 "执行了 getValue"因为a 已经是 1不需要默认值数组解构赋值的应用
快速交换变量(最经典):不用临时变量,本质是用数组打包 → 再解构
let a = 1;let b = 2;
[a, b] = [b, a];console.log(a, b); // 2 1函数返回多个值:替代“返回对象+手动取属性”
function getUser() { return ["Tom", 18];}
const [name, age] = getUser();console.log(name); // Tomconsole.log(age); // 18忽略不需要的值:中间用空位跳过
const [a, , c] = [1, 2, 3];
console.log(a); // 1console.log(c); // 3结合默认值(防 undefined): 常用于接口数据不完整时
const [a = 10, b = 20] = [1];
console.log(a); // 1console.log(b); // 20拆分函数返回的数组(API常见):很多“Promise封装库”都这么设计
const [data, error] = await fetchData();
if (error) { console.log("出错了");} else { console.log(data);}处理 split 字符串结果:超高频使用
const [year, month, day] = "2026-06-17".split("-");
console.log(year); // 2026console.log(month); // 06console.log(day); // 17遍历数组时同时取 index / value:配合 entries:
const arr = ["a", "b", "c"];
for (const [index, value] of arr.entries()) { console.log(index, value);}//输出://0 a//1 b//2 c解构 Map Map 天然就是可解构结构
const map = new Map([ ["name", "Tom"], ["age", 18]]);
for (const [key, value] of map) { console.log(key, value);}函数参数解构(非常重要):直接在参数里解构数组
function sum([a, b]) { return a + b;}
console.log(sum([3, 5])); // 8类数组解构
function fn() { const [a, b, c] = arguments; console.log(a, b, c);}fn(10, 20, 30);对象解构赋值的原理
从对象中快速提取属性并赋值给变量。
模式(结构)匹配
{}={}属性名相同的完成赋值
const { age, name } = { name: 'Alex', age: 18 };console.log(age, name);对象解构的本质
对象解构并不是创建新的对象,而是根据属性名从对象中读取对应的值,然后赋值给变量。
const { name, age } = user;//本质上等价于const name = user.name;const age = user.age;属性重命名
如果不想使用同名变量,可以进行重命名:
const user = { name: 'Tom', age: 18 };const { name: userName } = user;//等价于// const userName = user.name;console.log(userName); // Tom对象解构赋值的注意事项
对象解构赋值的默认值,默认值仅在属性值为 undefined 时生效。
/** * 1. 基本用法:没有对应属性时使用默认值 */const obj1 = {};
const { a = 10, b = 20 } = obj1;
console.log('1:', a, b); // 10 20
/** * 2. 有值时不使用默认值 */const obj2 = { a: 1 };
const { a: a2 = 10, b: b2 = 20 } = obj2;
console.log('2:', a2); // 1console.log('2:', b2); // 20
/** * 3. 重点:只有 undefined 才会触发默认值 * null 不会触发默认值 */const obj3 = { a: null };
const { a: a3 = 10 } = obj3;
console.log('3:', a3); // null ❗不是 10
/** * 4. 属性缺失 / undefined 才会触发默认值 */const obj4 = { a: 1, b: undefined };
const { a: a4 = 10, b: b4 = 20, c: c4 = 30 } = obj4;
console.log('4:', a4); // 1console.log('4:', b4); // 20(undefined -> 默认值)console.log('4:', c4); // 30(不存在 -> 默认值)
/** * 5. 默认值可以是表达式(惰性执行) */function getValue() { console.log('执行了 getValue()'); return 99;}
const obj5 = {};
const { a: a5 = getValue() } = obj5;
console.log('5:', a5); // 会触发 getValue()
/** * 6. 默认值不会重复执行(只有需要时才执行) */const obj6 = { a: 1 };
const { a: a6 = getValue() } = obj6;
console.log('6:', a6);// 不会执行 getValue()
/** * 7. 属性重命名 + 默认值 */const obj7 = {};
const { a: x7 = 10 } = obj7;
console.log('7:', x7); // 10
/** * 8. 嵌套对象解构 + 默认值 */const obj8 = {};
const {profile: { name: name8 = 'Anonymous' } = {} } = obj8;// ⚠️ 防止 profile 是 undefined
console.log('8:', name8); // Anonymous将一个已经声明的变量用于解构赋值
let b = 1;const { b } = { b: 2 };console.log(b);//报错
var b = 1;const { b } = { b: 2 };console.log(b);//报错
let c = 5;[c] = [2, 3, 4];console.log(c);//2 覆盖let c = 5
const c = 5;[c] = [2, 3, 4];console.log(c);//报错,接口出变量c,c是常量无法更改可以取到继承的属性
const { toString } = {};console.log(toString);const parent = { a: 10};
const obj = Object.create(parent);
obj.b = 20;
const { a, b } = obj;
console.log(a); // 10console.log(b); // 20对象解构:
obj ├── b: 20 (自身属性) └── [[Prototype]] └── a: 10 (继承属性)解构时:b → 在自身找到;a → 在原型链找到
常见错误:
解构 undefined
const { name } = undefined;//报错TypeError: Cannot destructure property 'name' of undefined//undefined.name 本身就是非法操作。解构 null
const { name } = null;//TypeError//null.name本身就是非法操作。解构只“读取”,不复制结构
const parent = { a: 1,};
const obj = Object.create(parent); //obj = {} 创建一个新对象 obj,并让它的原型指向 parent
const { a } = obj; //const a = 1
obj.a = 999;//这是在解构之后赋值的,所以a还是1,如果写在解构之前,a就是999
console.log(a); // 1 ❗不会变console.log(obj); //999console.log(parent.a); //1对象解构与数组解构的区别
| 特性 | 对象解构 | 数组解构 |
|---|---|---|
| 匹配方式 | 按属性名匹配 | 按位置匹配 |
| 是否依赖顺序 | 否 | 是 |
| 底层原理 | 属性读取 | 迭代器读取 |
| 典型写法 | { name } | [first] |
对象解构赋值的应用
//函数参数的解构赋值const logPersonInfo = ({ username, age }) => console.log(username, age);
logPersonInfo({ username: 'alex', age: 18 });
//复杂嵌套 模式匹配-跳过的用逗号const obj = { x: 1, y: [3, 4, 5], z: { a: 5, b: 6, },};// const { x, y, z } = obj;// console.log(x, y, z);const { x, y: [, b, c], //这个一定要写对属性名,根据属性名匹配 y: y, //第一个y是属性值,第二个y是常量 y, //简写} = obj;console.log(b, y);其它数据类型的解构赋值
字符串解构赋值:
//字符串解构赋值,可以数组解构也可以是对象const [a, b, c, , d] = 'hello';console.log(a, b, c, d);
const { 0: e, 1: f, length } = 'hello';console.log(e, f, length);数值和布尔值
// 数值和布尔值的解构赋值-没有意义-只能拿到的是方法,不是数字的“结构内容”。// 先将右边的值转为对象const { toString } = 123; //等价于:const { toString }new Number(123);console.log(toString);// 布尔值也一样const flag = true;const { toString, valueOf } = flag;console.log(toString); // function toString()undefined和null
- 这两个没法解构赋值,直接报错
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!














