
文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载解构赋值Destructuring Assignment是 ECMAScript 2015 引入的语法它允许将数组或对象拆包到一系列变量中是现代 JavaScript 日常开发中最常用的技巧之一。本文以《现代 JavaScript 教程》解构赋值章节及其配套练习题 1-destruct-user 为核心系统讲解对象解构的完整语法——属性重命名冒号映射、默认值、剩余模式、嵌套解构与智能函数参数并结合仓库内topSalary练习的源码与测试用例展示解构在真实代码中的典型用法。读完本文你将能够熟练写出简洁、健壮、可读性强的对象解构代码并正确应对属性缺失参数可选等常见场景。从一道练习题说起对象解构的三要素本仓库中有一道经典练习 1-destruct-user/task.md题目给出了一个用户对象let user { name: John, years: 30 };要求写一条解构赋值语句实现三个目标name属性赋值给变量nameyears属性赋值给变量age属性名与变量名不同isAdmin属性赋值给变量isAdmin且属性缺失时取默认值false。仓库中给出的官方答案solution.md只有一行却浓缩了对象解构的全部核心语法let user { name: John, years: 30 }; let {name, years: age, isAdmin false} user; alert( name ); // John alert( age ); // 30 alert( isAdmin ); // false这行代码同时用到了对象解构的三大要素同名属性直接提取name从user.name中取值赋给同名变量属性重命名冒号映射years: age表示把属性years的值赋给变量age默认值isAdmin false表示若属性isAdmin缺失则赋值为false。下文将逐一展开这三要素并延伸到更多进阶用法。对象解构的基础语法对象解构的通用形式为let {var1, var2} {var1:…, var2:…}等号右侧是已存在的对象等号左侧是描述取哪些属性、赋给哪些变量的模式pattern。最简单的场景是变量名与属性名完全一致let options { title: Menu, width: 100, height: 200 }; let {title, width, height} options; alert(title); // Menu alert(width); // 100 alert(height); // 200与数组解构不同对象解构的变量顺序无关紧要——因为对象本身就是按键名查找的。下面两种写法完全等价// 改变 let {...} 中元素的顺序 let {height, width, title} { title: Menu, height: 200, width: 100 }属性重命名冒号映射{ sourceProperty: targetVariable }当属性名不适合直接作为变量名例如与现有变量冲突、或想用更短的别名时可以用冒号把属性映射到新变量let options { title: Menu, width: 100, height: 200 }; // { sourceProperty: targetVariable } let {width: w, height: h, title} options; // width - w // height - h // title - title alert(title); // Menu alert(w); // 100 alert(h); // 200冒号的语义是从对象中哪个属性取值赋值给哪个变量。上面的1-destruct-user练习答案中years: age正是这一语法的直接应用——保留对象的语义化属性名years同时把数据装进业务中更通用的变量名age。默认值为缺失属性兜底如果属性在对象中不存在解构不会报错变量会被赋值为undefined。此时可以用提供默认值let options { title: Menu }; let {width 100, height 200, title} options; alert(title); // Menu alert(width); // 100 alert(height); // 200关键细节默认值只在属性缺失时生效。如果属性存在即使值为undefined之外的任何值默认值都会被忽略。默认值不限于字面量可以是任意表达式甚至函数调用且仅在未提供对应值时才会被求值let options { title: Menu }; let {width prompt(width?), title prompt(title?)} options; alert(title); // Menu不弹窗 alert(width); // (prompt 的返回值弹窗)因为title存在prompt(title?)根本不会执行而width缺失才会触发prompt。这种按需求值特性对避免不必要的开销例如昂贵的计算、网络请求很有价值。冒号与等号组合重命名 默认值对象解构允许把冒号映射与默认值写在同一项里语法为{ sourceProperty: targetVariable defaultValue }let options { title: Menu }; let {width: w 100, height: h 200, title} options; alert(title); // Menu alert(w); // 100 alert(h); // 200这里width缺失所以变量w取默认值100若options.width存在则w直接取该属性值。这正是练习答案{name, years: age, isAdmin false}的完整形态years: age是重命名isAdmin false是默认值两者可以自由组合。剩余模式...rest收集其余属性当对象属性比声明的变量多时可以用剩余模式rest pattern把剩余属性收集进一个新对象let options { title: Menu, height: 200, width: 100 }; // title 名为 title 的属性 // rest 存有剩余属性的对象 let {title, ...rest} options; // 现在 titleMenu, rest{height: 200, width: 100} alert(rest.height); // 200 alert(rest.width); // 100注意事项...rest必须位于模式中的最后一个位置否则会抛出语法错误。数组解构同样支持剩余模式let [name1, name2, ...rest] [...]两者的语义一致。不使用let时的陷阱{...}与代码块的歧义如果变量已经存在想通过解构给它们重新赋值不能直接写{...} objlet title, width, height; // 这一行会发生错误 {title, width, height} {title: Menu, width: 200, height: 100};原因在于JavaScript 会把主代码流中不在其他表达式内的{...}解析为代码块而不是对象模式。解决办法是把整个赋值表达式用括号包裹明确告诉引擎这是表达式let title, width, height; // 现在就可以了 ({title, width, height} {title: Menu, width: 200, height: 100}); alert( title ); // Menu这是一个非常容易踩坑的细节在函数体内给已声明变量重新赋值时尤其常见。嵌套解构提取深层数据结构当对象里嵌套对象、数组嵌套数组时等号左侧可以使用与右侧结构相同的模式逐层提取let options { size: { width: 100, height: 200 }, items: [Cake, Donut], extra: true }; // 为了清晰起见解构赋值语句被写成多行的形式 let { size: { // 把 size 的内容解构到这里 width, height }, items: [item1, item2], // 把 items 的内容解构到这里 title Menu // 对象中不存在使用默认值 } options; alert(title); // Menu alert(width); // 100 alert(height); // 200 alert(item1); // Cake alert(item2); // Donut上面代码的运行结构如下图所示注意两点size与items本身不会被赋值给变量——我们取的是它们的内容未被模式匹配的属性如extra会被忽略。嵌套解构是解析 API 响应、配置对象等深层 JSON 数据时的高效手段。智能函数参数用对象解构替代冗长的位置参数函数参数过多且大多可选时传统写法会非常痛苦。以创建菜单的函数为例朴素实现是function showMenu(title Untitled, width 200, height 100, items []) { // ... }调用时若只想改items必须用undefined占位可读性极差// 在采用默认值的位置设置 undefined showMenu(My Menu, undefined, undefined, [Item1, Item2])对象解构参数是标准解法调用方传一个对象函数在参数位置直接解构// 我们传递一个对象给函数 let options { title: My menu, items: [Item1, Item2] }; // ……然后函数马上把对象解构成变量 function showMenu({title Untitled, width 200, height 100, items []}) { // title, items – 提取于 options // width, height – 使用默认值 alert( ${title} ${width} ${height} ); // My Menu 200 100 alert( items ); // Item1, Item2 } showMenu(options);还可以把重命名、默认值、嵌套解构全部用上function showMenu({ title Untitled, width: w 100, // width goes to w height: h 200, // height goes to h items: [item1, item2] // items 的第一个元素给 item1第二个给 item2 }) { alert( ${title} ${w} ${h} ); // My Menu 100 200 alert( item1 ); // Item1 alert( item2 ); // Item2 } showMenu(options);其完整语法与普通对象解构一致function({ incomingProperty: varName defaultValue ... })空参数对象的兜底 {}对象解构参数有一个重要前提函数必须收到一个对象参数。直接调用showMenu()会因无法对undefined解构而抛错。解决办法是为整个参数对象设置默认值function showMenu({ title Menu, width 100, height 200 } {}) { alert( ${title} ${width} ${height} ); } showMenu(); // Menu 100 200{...} {}中的 {}表示若调用方没传参数则用一个空对象来解构这样所有内部默认值都能生效。这是在函数参数设计中使用解构的标准写法。仓库源码佐证解构 Object.entries遍历键值对对象解构最典型的实战场景是与Object.entries()搭配在for..of循环中直接解构出键和值。仓库中的 6-max-salary 练习要求从薪资对象中找出最高收入者的姓名官方答案 solution.js 正是这一组合的教科书式用法function topSalary(salaries) { let maxSalary 0; let maxName null; for(let [name, salary] of Object.entries(salaries)) { if (maxSalary salary) { maxSalary salary; maxName name; } } return maxName; }这里Object.entries(salaries)返回[[John, 100], [Pete, 300], [Mary, 250]]形式的数组for(let [name, salary] of ...)在每次迭代中把键值对数组解构为name与salary两个变量。配套的测试用例 test.js 验证了两个边界行为describe(topSalary, function() { it(returns top-paid person, function() { let salaries { John: 100, Pete: 300, Mary: 250 }; assert.equal( topSalary(salaries), Pete ); }); it(returns null for the empty object, function() { assert.isNull( topSalary({}) ); }); });正常情况返回最高薪资者Pete空对象时maxName保持初始值null函数返回null。对于Map类型遍历同样可以直接解构因为 Map 本身就是以[key, value]对的形式迭代的let user new Map(); user.set(name, John); user.set(age, 30); // Map 以 [key, value] 对的形式迭代非常便于解构 for (let [key, value] of user) { alert(${key}:${value}); // name:John, then age:30 }补充数组解构要点速览虽然本文聚焦对象解构但数组解构与其共用同一套思想默认值、剩余模式了解其要点有助于融会贯通// 基本用法与 split 结合 let [firstName, surname] John Smith.split( ); // 用逗号跳过不想要的元素 let [firstName, , title] [Julius, Caesar, Consul, of the Roman Republic]; // 等号右侧可以是任何可迭代对象 let [a, b, c] abc; // [a, b, c] let [one, two, three] new Set([1, 2, 3]); // 赋值给对象属性 let user {}; [user.name, user.surname] John Smith.split( ); // 交换两个变量的值著名技巧 [guest, admin] [admin, guest]; // 默认值与剩余模式 let [name Guest, surname Anonymous] [Julius]; let [name1, name2, ...rest] [Julius, Caesar, Consul, of the Roman Republic];一个重要认知是解构不会破坏原数据结构它只是把数组/对象中的值复制给变量let [a, b] arr与let a arr[0]; let b arr[1];完全等价只是写法更简洁。总结对象解构完整语法对象解构的完整语法let {prop : varName default, ...rest} object属性prop被赋值给变量varName若属性缺失则用默认值default未被映射的剩余属性被收集进rest对象。数组解构的完整语法let [item1 default, item2, ...rest] array数组第一项给item1、第二项给item2其余项复制进新数组rest。嵌套解构等号左侧模式与右侧数据结构保持相同形状即可层层提取可用于解析嵌套 JSON。智能函数参数用{ title Menu, width 100, height 200 } {}形式的解构参数替代冗长的位置参数列表配合默认值即可优雅处理大部分参数可选的场景——这是现代 JavaScript 组件库、工具函数中最普遍的函数签名模式。回到开篇的练习let {name, years: age, isAdmin false} user;一行代码同时示范了同名提取、冒号重命名与默认值三大能力。掌握对象解构你将能用更少的代码、更清晰地表达数据取用意图并显著减少因参数漏传、属性缺失引发的undefined类 bug。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐现代 JavaScript 教程实践对象解构赋值、属性重命名与默认值zh.javascript.info 解构赋值章节实战现代 JavaScript 教程实践对象解构赋值、属性重命名与默认值zh.javascript.info 解构赋值章节实战 本篇技术指南围绕《现代 Jav文档教程前端JavaScript 对象解构赋值实战属性提取、重命名与默认值——Modern JavaScript Tutorial destruct-user 任务精讲JavaScript 对象解构赋值实战属性提取、重命名与默认值——Modern JavaScript Tutorial destruct user 任务精讲文档/教程前端JavaScript 对象解构赋值实战从属性重命名到嵌套解构与默认值Modern JavaScript Tutorial 练习精讲JavaScript 对象解构赋值实战从属性重命名到嵌套解构与默认值Modern JavaScript Tutorial 练习精讲 导读 本文围绕 Mod文档/教程前端上一篇AngularFun部署指南将参考架构应用到生产环境的完整步骤下一篇告别混乱MIDIMagenta构建高质量音乐语料库的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考