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 }) };

相关推荐
风骏时光牛马18 分钟前
AI稳定性治理体系构建与疑难问题深度分析
前端
LMT流氓兔34 分钟前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真41 分钟前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放1 小时前
Python基础语法练习题(75)
开发语言·python·学习
IT_陈寒1 小时前
JavaScript的this坑人实录,这次我真的记下来了
前端·人工智能·后端
starzy19902 小时前
Scala循环与判断:一切皆表达式的控制流
开发语言·人工智能·scala
starzy19902 小时前
Scala类和对象:从构造器到样例类的完整指南
开发语言·后端·scala
开开心心就好2 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
niucloud-admin2 小时前
NIUCLOUD PHP SAAS上门家政使用文档--服务订单:订单列表
开发语言·php
怪我冷i2 小时前
Rust 的impl语法详解
开发语言·后端·rust