104 Destructuring Objects(对象解构)笔记

一、对象解构基础用法

1.1 核心语法与规则

  • 语法格式:使用{}包裹需提取的属性名,等号右侧为目标对象,即const {属性名1, 属性名2,...} = 目标对象

  • 关键规则

    • 变量名必须与对象属性名完全匹配(大小写敏感)。
    • 属性顺序不影响解构结果(与数组解构不同,无需手动跳过元素)。
    • 解构后会创建与属性名对应的新变量,直接使用即可。

1.2 例题

假设存在一个餐厅对象,包含名称、营业时间、菜品类别等属性,使用基础解构提取关键信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 目标对象
const restaurant = {
name: "Italian Bistro",
openingHours: {
mon: { open: 10, close: 22 },
fri: { open: 11, close: 23 },
},
categories: ["Pasta", "Pizza", "Salad"],
};

// 解构提取name、openingHours、categories属性
const { name, openingHours, categories } = restaurant;

// 输出结果
console.log(name); // "Italian Bistro"(餐厅名称)
console.log(openingHours); // {mon: {open:10, close:22}, fri: {open:11, close:23}}(营业时间)
console.log(categories); // ["Pasta", "Pizza", "Salad"](菜品类别)

二、自定义解构变量名

2.1 核心语法与场景

  • 语法格式:当需要变量名与属性名不同时,使用属性名: 新变量名格式,即const {属性名: 新变量名,...} = 目标对象
  • 适用场景:处理第三方数据(如 API 返回结果)时,属性名可能不符合项目命名规范(如属性名过长、大小写不统一),需自定义简洁变量名。

2.2 例题

基于上述餐厅对象,将属性名自定义为更简洁的变量名:

1
2
3
4
5
6
7
8
9
10
11
// 解构时自定义变量名:name→restaurantName,openingHours→hours,categories→tags
const {
name: restaurantName,
openingHours: hours,
categories: tags,
} = restaurant;

// 输出结果(需使用自定义变量名)
console.log(restaurantName); // "Italian Bistro"
console.log(hours); // {mon: {open:10, close:22}, fri: {open:11, close:23}}
console.log(tags); // ["Pasta", "Pizza", "Salad"]

三、解构时设置默认值

3.1 核心语法与作用

  • 语法格式

    :通过

    1
    属性名 = 默认值

    设置默认值,支持结合自定义变量名(

    1
    属性名: 新变量名 = 默认值

    ),即:

    • 基础默认值:const {属性名 = 默认值,...} = 目标对象
    • 结合自定义变量名:const {属性名: 新变量名 = 默认值,...} = 目标对象
  • 核心作用:避免解构对象中不存在的属性时,变量值变为undefined,尤其适用于数据结构不确定的场景(如 API 返回数据可能缺失部分字段)。

3.2 例题

假设餐厅对象可能缺失menu属性,starterMenu属性需自定义变量名并设置默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 目标对象(缺失menu属性,存在starterMenu属性)
const restaurant = {
name: "Italian Bistro",
starterMenu: ["Garlic Bread", "Bruschetta"],
};

// 解构:menu设默认值空数组,starterMenu→starters且设默认值空数组
const {
menu = [], // 对象中无menu,使用默认值[]
starterMenu: starters = [], // 有starterMenu,使用实际值,不触发默认值
} = restaurant;

// 输出结果
console.log(menu); // [](默认值生效)
console.log(starters); // ["Garlic Bread", "Bruschetta"](实际值生效)

四、解构时变异变量(修改已声明变量)

4.1 核心语法与注意事项

  • 问题场景:若变量已提前声明(用let定义),直接解构会因{}被 JS 识别为 “代码块” 而报错(代码块无法赋值)。
  • 解决方案:将解构语句用()包裹,强制 JS 将其识别为 “表达式”,语法为({属性名1, 属性名2,...} = 目标对象)
  • 注意事项:变异变量时,不能使用constconst声明的变量不可修改),需用let声明初始变量。

4.2 例题

提前声明变量ab,通过解构修改其值:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 提前声明已存在的变量(必须用let,不可用const)
let a = 10;
let b = 20;

// 目标对象(需修改a、b的值为该对象的a、b属性)
const obj = { a: 23, b: 7, c: 14 };

// 变异变量:用()包裹解构语句,避免语法错误
({ a, b } = obj);

// 输出结果(变量值已被修改)
console.log(a); // 23
console.log(b); // 7

五、嵌套对象解构

5.1 核心语法与逻辑

  • 语法逻辑

    :嵌套对象需按照 “对象层级结构” 逐层解构,内层对象同样用

    1
    {}

    包裹,格式为:

    • 基础嵌套解构:const {外层属性名: {内层属性名1, 内层属性名2,...}} = 目标对象
    • 结合自定义变量名:const {外层属性名: {内层属性名: 新变量名,...}} = 目标对象
  • 关键逻辑:先定位到外层属性,再从外层属性对应的内层对象中提取目标属性。

5.2 例题

从餐厅对象的openingHours(外层属性,值为嵌套对象)中,提取周五的营业时间并自定义变量名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 目标对象(openingHours为嵌套对象)
const restaurant = {
name: "Italian Bistro",
openingHours: {
fri: { open: 11, close: 23 },
sat: { open: 9, close: 24 },
},
};

// 嵌套解构:从openingHours中提取fri的open→o、close→c
const {
openingHours: {
fri: { open: o, close: c },
},
} = restaurant;

// 输出结果
console.log(o); // 11(周五开门时间)
console.log(c); // 23(周五关门时间)

六、对象解构在函数参数中的应用

6.1 核心语法与优势

  • 语法格式

    :函数定义时,直接对参数对象解构,支持设置默认值,格式为:

    1
    2
    3
    function 函数名({属性名1 = 默认值, 属性名2 = 默认值,...}) {
    // 函数体内直接使用解构后的变量
    }
  • 核心优势

    • 解决 “参数过多且顺序难记” 的问题(调用函数时无需关注参数顺序,只需传递对象)。
    • 可直接为参数设置默认值,避免函数体内重复判断。

6.2 例题

创建 “订单交付” 函数,接收地址、菜品索引、时间等参数,通过解构简化参数处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 定义函数:参数对象解构,设置默认值(starterIndex=1,mainIndex=0,time='20:00')
const orderDelivery = ({
starterIndex = 1,
mainIndex = 0,
time = "20:00",
address, // 地址为必填项,不设默认值
}) => {
// 函数体内直接使用解构后的变量
console.log(`订单已确认:
开胃菜:${["Garlic Bread", "Bruschetta"][starterIndex]}
主菜:${["Pasta", "Pizza"][mainIndex]}
配送时间:${time}
配送地址:${address}
`);
};

// 调用函数:仅传递address和starterIndex,其他参数使用默认值
orderDelivery({
address: "Via del Sole, 21",
starterIndex: 0,
});

// 输出结果(mainIndex和time使用默认值)
/*
订单已确认:
开胃菜:Garlic Bread(starterIndex=0)
主菜:Pasta(mainIndex默认0)
配送时间:20:00(time默认值)
配送地址:Via del Sole, 21
*/

七、总结:对象解构核心要点

功能场景 核心语法示例 关键注意事项
基础提取属性 const {a,b} = obj 变量名与属性名必须完全匹配
自定义变量名 const {a: newA, b: newB} = obj 新变量名才是最终可用的变量
设置默认值 const {a=1, b: newB=2} = obj 仅当属性不存在时默认值生效
变异已声明变量 ({a,b} = obj) 必须用()包裹,初始变量用let声明
嵌套对象解构 const {a: {b: newB}} = obj 按层级结构逐层解构,内层用{}包裹
函数参数解构 fn({a=1, b=2}) 调用时传递对象,无需关注参数顺序