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=0;greet({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 }) };

相关推荐
2501_93392325几秒前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka
染指111020 分钟前
142.Agent-多Agent框架-通过Skills实现多Agent
开发语言·人工智能·python·langchain·agents
骑着蜗牛撵大象32722 分钟前
LangChain 工具调用从声明到闭环:给智能体接上真实的手脚
前端
数据掘金33 分钟前
百度统计后台页面数据异常?从手动调用时机开始排查
前端
hunteritself34 分钟前
10 层 4K 实时剪辑,国产工作站进入广电制作核心
大数据·前端·人工智能·深度学习·transformer
踩着两条虫35 分钟前
我在浏览器里“盖”了一个村:Vue + Three.js 大屏开发踩坑记
前端·vue.js·three.js
好好学习O(∩_∩)O37 分钟前
[QT] 多线程moveToThread 和易踩的8个坑
开发语言·qt
默_笙38 分钟前
🧀 让大模型的答案"流"出来:NestJS AI 模块 + SSE + RxJS 实战
javascript·人工智能
mbshqqb40 分钟前
TypeScript基础教程之同步生成器
前端·javascript·typescript
我是人✓1 小时前
Java核心语法:作用域、循环与大数值处理
java·开发语言·后端