ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

zh.javascript.info 教程实战:用 Array.sort 按年龄对对象数组排序(sortByAge 精讲)

zh.javascript.info 教程实战:用 Array.sort 按年龄对对象数组排序(sortByAge 精讲) 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本篇技术指南以《现代 JavaScript 教程》zh.javascript.info数组方法章节中的经典练习“按年龄对用户排序”8-sort-objects为核心完整讲解如何为对象数组编写比较函数并通过sortByAge一行代码解决按age属性升序排序的问题。读完本文你将掌握Array.prototype.sort的原位排序机制、比较函数返回值约定以及对象数组在实际业务场景用户列表、排行榜、表格数据中的排序套路并能顺手解决同章节的降序排序、复制排序等变体问题。任务速览sortByAge 要解决什么问题任务位于 1-js/05-data-types/05-array-methods/8-sort-objects/task.md原始要求非常简洁编写函数sortByAge(users)读取对象数组的age属性并根据age对数组中的对象进行排序。题目给出的数据如下let john { name: John, age: 25 }; let pete { name: Pete, age: 30 }; let mary { name: Mary, age: 28 }; let arr [ pete, john, mary ]; sortByAge(arr); // now: [john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete注意两个容易被忽略的细节输入数组故意是乱序的pete(30)、john(25)、mary(28)只有排序函数正确结果才会变成john(25)、mary(28)、pete(30)。排序后访问的是对象属性arr[0].name必须输出John这验证了排序移动的是数组中的对象引用对象本身及其name、age属性保持不变。参考解法一行箭头函数完成升序排序官方参考解法见 1-js/05-data-types/05-array-methods/8-sort-objects/solution.mdfunction sortByAge(arr) { arr.sort((a, b) a.age - b.age); } let john { name: John, age: 25 }; let pete { name: Pete, age: 30 }; let mary { name: Mary, age: 28 }; let arr [ pete, john, mary ]; sortByAge(arr); // 排序后的数组为[john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete解法只有一条核心语句arr.sort((a, b) a.age - b.age)。它之所以成立依赖的是本章 array-methods/article.md 中sort(fn)一节讲解的三条原理。理解它们才算真正吃透这道题。原理一sort 是原位in-place排序arr.sort(fn)对数组进行原位排序直接更改原数组中元素的顺序并返回排序后的数组。返回值通常被忽略因为arr本身已经被修改了。这正是题目要求sortByAge(arr)直接修改传入数组、之后用alert(arr[0].name)验证结果的前提——函数内部不需要return新数组只需对入参数组调用sort即可。对比默认 sort 的“字符串排序”陷阱教程 article.md 里特意用一个例子提醒初学者直接调用arr.sort()会把所有元素转换为字符串再按字典序比较let arr [ 1, 2, 15 ]; arr.sort(); alert( arr ); // 1, 15, 2结果变成1, 15, 2因为字符串15按字典序排在2前面。同理如果本题直接调用arr.sort()对象会被转成[object Object]这样的字符串排序毫无意义。所以对对象数组排序必须提供自定义比较函数。原理二比较函数的返回值约定教程给出了比较函数的标准形态function compare(a, b) { if (a b) return 1; // 第一个值比第二个值大 if (a b) return 0; // 两个值相等 if (a b) return -1; // 第一个值比第二个值小 }关键约定教程在“比较函数可以返回任何数字”提示框中明确说明比较函数只需要返回正数表示“大于”、负数表示“小于”并不要求必须是1或-1。于是针对数值属性可以用减法把三分支压缩成一行arr.sort(function(a, b) { return a - b; }); // 数值升序a.age - b.age的语义拆解a.age b.age时结果为负数 →a排在b前面升序相等时为0→ 顺序不变排序算法视实现而定现代引擎多为稳定排序a.age b.age时为正数 →a排在b后面。这就是sortByAge解法的全部数学内核。原理三箭头函数让比较函数更简洁教程紧接着给出箭头函数版本见“箭头函数最好”提示框arr.sort( (a, b) a - b );它与上面更长的function版本完全等价区别只是语法更短。本题解法的(a, b) a.age - b.age正是这种写法的对象版箭头函数的两个参数a、b分别是数组中的两个相邻待比较对象函数体直接读取它们的age字段做减法。举一反三同章节的三个变体练习理解了上述原理同章节的其他排序/对象数组练习题都能顺手解决这也证明sort比较函数是这一章的核心技能点。1. 降序排列4-sort-back4-sort-back/task.md 要求把[5, 2, 1, -10, 8]降序排列官方解法见 solution.mdlet arr [5, 2, 1, -10, 8]; arr.sort((a, b) b - a); alert( arr ); // 8, 5, 2, 1, -10与升序版对比b - a把减法的两个操作数对调符号反转排序方向随之反转。想给对象数组按age降序同样只需arr.sort((a, b) b.age - a.age)。2. 复制后排序5-copy-sort-array5-copy-sort-array/task.md 要求得到排序副本但保持原数组不变。因为sort是原位修改必须先复制再排序let sorted arr.slice().sort();slice()无参调用会返回原数组的浅拷贝副本见 article.md 中slice一节副本上排序不影响原数组。这与sortByAge直接修改入参的语义正好互补前者是“复制 排序”后者是“原位排序”。3. 对象数组的其他处理7-map-objects 与 10-average-age同章还有两道配套练习可以巩固对象数组操作7-map-objects用map把{ name, surname, id }数组映射成{ fullName, id }数组——排序前的数据整形常用map10-average-age用reduce求对象数组age的平均值——排序后的排名、统计场景常与reduce配合。边界情况与工程实践建议从源码级视角看arr.sort(fn)内部是通用排序算法教程指出现代引擎通常基于快排或 Timsort 优化它会多次调用我们的比较函数且每次比较只针对数组中的两个元素。因此编写比较函数时建议注意以下几点年龄字段缺失或非数值a.age - b.age遇到undefined会得到NaN而NaN参与比较时排序结果不可预期。生产代码建议先用filter或默认值处理缺失字段再排序。相等年龄保持稳定现代 JS 引擎的sort是稳定排序稳定排序是 ES2019 规范要求相同age的对象会保持原有相对顺序无需额外处理但不要依赖比较函数返回0之外的值去“打乱”相等元素。不要直接修改age排序移动的是数组元素对象引用对象属性本身不会被改写若需要“按年龄复制一份排序结果”先slice()再排序即可对应 5-copy-sort-array 的思路。字符串字段排序用localeCompare如果将来要按name排序直接a.name b.name ? 1 : -1对带变音符号的字符会出错教程建议使用a.name.localeCompare(b.name)见 article.md 的 “localeCompare” 提示框。小结“按年龄对用户排序”这道题是数组方法章节中sort(fn)知识点的最佳实战载体一行arr.sort((a, b) a.age - b.age)背后浓缩了三个核心原理sort是原位排序直接修改原数组比较函数按正数 / 负数 / 零的约定决定先后顺序减法写法是数值比较的最简形式箭头函数让比较函数保持简洁可读。掌握它之后升序a - b、降序b - a、复制后排序slice().sort()以及对象数组的各种属性排序都能信手拈来。想继续巩固可直接查看 数组方法章节完整文章 及其余练习任务目录如 8-sort-objects、4-sort-back、5-copy-sort-array逐题演练。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐JavaScript Tutorial用 sortByAge 对对象数组按 age 排序的完整实战解析JavaScript Tutorial用 sortByAge 对对象数组按 age 排序的完整实战解析 导读 本篇技术指南围绕《Modern JavaScri文档/教程前端zh.javascript.info 实战用 reduce 实现对象数组平均年龄计算getAverageAgezh.javascript.info 实战用 reduce 实现对象数组平均年龄计算getAverageAge 导读 本文围绕《现代 JavaScript文档教程前端JavaScript 数组降序排序Array.sort 比较函数实战指南zh.javascript.info 习题精解JavaScript 数组降序排序Array.sort 比较函数实战指南zh.javascript.info 习题精解 本篇技术指南以《现代 JavaSc文档教程前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进