js 解构赋值

概念与要点

  • 解构赋值ES6 引入的语法糖,用于按"模式匹配"从数组对象中提取值并赋给变量,能显著简化取值与传参代码。
  • 数组解构按位置 匹配;对象解构按属性名匹配,顺序无关。
  • 可配合默认值剩余元素 ...重命名嵌套解构使用。
  • 右侧不是可迭代对象(数组解构)或右侧为 null/undefined(对象解构)会报错,需要做好容错处理。

数组解构

  • 基本用法
    • 按顺序取值:const [a, b] = [1, 2]; // a=1, b=2
  • 跳过元素
    • 使用逗号占位:const [a, , c] = [1, 2, 3]; // a=1, c=3
  • 默认值
    • 仅当值为 undefined 时生效:const [x=10, y=20] = [5]; // x=5, y=20;注意 null 不会触发默认值。
  • 剩余元素
    • 收集剩余项:const [head, ...tail] = [1,2,3,4]; // head=1, tail=[2,3,4]
  • 可迭代性
    • 右侧只要是可迭代对象 即可:let [a,b,c] = 'abc'; // a='a',b='b',c='c'let [x,y] = new Set([1,2]);
  • 交换变量
    • 一行交换:[a, b] = [b, a];
  • 常见陷阱
    • 右侧非可迭代会报错:let [foo] = 1; // TypeError

对象解构

  • 基本用法
    • 按属性名取值:const {name, age} = {name:'Alice', age:25}; // name='Alice', age=25
  • 重命名
    • 将属性映射到新变量:const {name: fullName, age: years} = user;
  • 默认值
    • 属性缺失或值为 undefined 时使用:const {theme='dark', lang='en'} = settings;
  • 剩余属性
    • 收集其余属性:const {a, ...rest} = {a:1,b:2,c:3}; // rest={b:2,c:3}
  • 嵌套解构
    • 与数组/对象混合:const {user:{name}, posts:[first]} = data;
  • 常见陷阱
    • 右侧为 null/undefined 会报错:const {x} = null; // TypeError;可用空对象兜底:const {x} = maybeObj || {};
    • 解构到已声明变量需加括号:let x; ({x} = {x:1});

函数参数解构

  • 数组参数
    • 直接解构参数:function sum([a,b]) { return a+b; } sum([1,2]); // 3
  • 对象参数
    • 命名参数更清晰:function greet({name, age}) { ... } greet({name:'Bob',age:30});
  • 默认值与空对象兜底
    • 同时给"参数对象"和"属性"默认值更安全:
      • function greet({name='Guest', age=0} = {}) { ... }
      • 调用:greet(); // name='Guest', age=0greet({name:'Tom'}); // age=0
        常见用法与最佳实践
  • 交换变量:[a, b] = [b, a];
  • 从函数返回多值:
    • function getUser(){ return {name:'Tom', age:30}; } const {name, age} = getUser();
  • 处理 API 响应:
    • fetch('/api').then(r=>r.json()).then(({id, name, email})=>{ ... });
  • 遍历键和值:
    • for (const [k, v] of Object.entries(obj)) { ... }
  • 容错与兜底:
    • 对象解构前:const {a=1, b=2} = maybeObj || {};
    • 深度解构前确保中间层级存在:const {user: {profile: {city=''}}} = data ?? {};
  • 可迭代与字符串:
    • const [a,b] = 'hi'; // a='h', b='i'const {length} = 'abc'; // length=3
  • 易错点速记:
    • 数组解构依赖顺序;对象解构依赖属性名。
    • 默认值仅在值为 undefined 时生效(null 不触发)。
    • 右侧需可迭代(数组解构);对象解构右侧不可为 null/undefined
    • 已声明变量做对象解构需加括号:({x}=obj);

先声明变量再解构赋值的正确写法

数组解构 先声明后赋值

  • 先声明变量,再用解构给已声明变量赋值,语法为:[a, b] = 右侧可迭代对象;。右侧必须是可迭代对象(如数组、字符串、Set、Map 等)。
  • 支持默认值[x=10, y=20] = [5]; // x=5, y=20
  • 支持剩余元素[head, ...tail] = [1,2,3]; // tail=[2,3];注意剩余元素必须是最后一个。
  • 常见用途:一行交换变量[a, b] = [b, a];
  • 易错点:右侧为 null/undefined 会抛出错误(数组解构要求右侧可迭代)。

对象解构 先声明后赋值

  • 先声明变量,再用解构给已声明变量赋值,语法为:({ a, b } = 对象);。由于 {...} 会被解析为代码块,必须用小括号 包裹:({ a, b } = obj);
  • 支持重命名({ name: fullName, age: years } = user);
  • 支持默认值({ theme='dark', lang='en' } = settings);;仅当属性值为 undefined 时生效(null 不触发默认值)。
  • 支持剩余属性({ a, ...rest } = {a:1,b:2,c:3}); // rest={b:2,c:3}
  • 易错点:右侧为 null/undefined 会抛出错误;已声明变量做对象解构必须加括号

常见陷阱与最佳实践

  • 右侧合法性:数组解构右侧必须可迭代 ;对象解构右侧不能为 null/undefined 。不确定时可兜底:const [a] = maybeArr || [];const {x} = maybeObj || {};
  • 分号与括号:对象无声明解构必须加括号 ;若上一行以 [( 结尾,需在行首加分号以避免被当作上一行表达式继续解析:;[a, b] = [1, 2];
  • 默认值生效条件:仅在值为 undefined 时生效(null 不会触发默认值)。
  • 剩余元素位置:...rest 必须是解构模式的最后一项,否则语法错误。

速查示例

js 复制代码
// 数组:先声明后赋值
let a, b, rest;
[a, b] = [1, 2];            // a=1, b=2
[a, b = 10] = [5];          // a=5, b=10(默认值)
[a, ...rest] = [1,2,3];    // rest=[2,3]
[a, b] = [b, a];            // 交换:a=2, b=1

// 对象:先声明后赋值(注意小括号)
let x, y, z;
({ x, y } = { x: 1, y: 2 }); // x=1, y=2
({ x: foo, y: bar } = { x: 1, y: 2 }); // foo=1, bar=2
({ x = 10, y = 20 } = { x: 5 }); // x=5, y=20(默认值)
({ a, ...rest } = { a: 1, b: 2, c: 3 }); // rest={b:2,c:3}

对象为什么要使用小括号

{在语句开头会被解析为代码块,加 ()​ 将其转为合法的表达式上下文

将对象字面量作为表达式使用场景

箭头函数直接返回对象:const f = () => ({ name: 'Tom' });

立即调用函数表达式:(function(){ /* ... */ })();

作为对象属性:const o = { data: ({ id: 1 }) };

相关推荐
代码猎人2 分钟前
substring和substr有什么区别
前端
pimkle2 分钟前
visactor vTable 在移动端支持 ellipsis 气泡
前端
donecoding2 分钟前
告别 scrollIntoView 的“越级滚动”:一行代码解决横向滚动问题
前端·javascript
0__O2 分钟前
如何在 monaco 中实现自定义语言的高亮
前端·javascript·编程语言
海奥华23 分钟前
Golang Channel 原理深度解析
服务器·开发语言·网络·数据结构·算法·golang
Jasmine_llq4 分钟前
《P3200 [HNOI2009] 有趣的数列》
java·前端·算法·线性筛法(欧拉筛)·快速幂算法(二进制幂)·勒让德定理(质因子次数统计)·组合数的质因子分解取模法
呆头鸭L5 分钟前
快速上手Electron
前端·javascript·electron
代码游侠5 分钟前
学习笔记——MQTT协议
开发语言·笔记·php
Aliex_git9 分钟前
性能指标笔记
前端·笔记·性能优化
秋天的一阵风9 分钟前
🌟 藏在 Vue3 源码里的 “二进制艺术”:位运算如何让代码又快又省内存?
前端·vue.js·面试