深入理解JavaScript对象数组按属性排序及其TypeScript实践

深入理解JavaScript对象数组按属性排序及其TypeScript实践

本文旨在深入解析JavaScript中 Array.prototype.sort() 方法与自定义比较函数的使用,特别是如何通过一个名为 propSort 的实用函数实现对象数组按指定数值属性进行排序。我们将详细剖析 propSort 的工作原理,包括 a[prop] 语法和 null/undefined 值的处理,并探讨将其转换为TypeScript时的类型定义、泛型应用及潜在的类型安全问题,提供专业的TypeScript实践方案。

JavaScript Array.prototype.sort() 基础

javascript 的 array.prototype.sort() 方法用于对数组的元素进行原地排序,并返回数组。默认情况下,sort() 方法会将数组元素转换为字符串,然后按照它们的 utf-16 码元值顺序进行排序。然而,对于数值或复杂对象排序,这种默认行为往往不符合预期。

为了实现自定义排序逻辑,sort() 方法可以接受一个可选的比较函数作为参数。这个比较函数通常接收两个参数 a 和 b,它们代表了数组中正在被比较的两个元素。比较函数的返回值决定了 a 和 b 在排序后的相对位置:

如果 compareFunction(a, b) 返回值小于 0,则 a 会被排在 b 之前。如果 compareFunction(a, b) 返回值大于 0,则 b 会被排在 a 之前。如果 compareFunction(a, b) 返回值等于 0,则 a 和 b 的相对位置不变(但 ECMAScript 标准不保证此行为,某些浏览器可能会改变)。

理解比较函数的返回值机制是实现复杂排序的关键。

propSort 函数解析

我们来看一个典型的 propSort 函数,它旨在根据对象数组中指定数值属性的值进行排序。

/** * sort array by numeric by numeric property values * of object entries. null entries are treated as 0. * array entries must be objects. * @param {object[]} arr - The array of objects to sort. * @param {string} prop - The numeric property name (string) to sort on. */export const propSort = (arr, prop) => {    arr.sort((a, b) => {        return (a[prop] || 0) - (b[prop] || 0);    });};

该 propSort 函数是对 Array.prototype.sort() 方法的一个封装,其核心在于传递给 sort() 的匿名比较函数 (a, b) => { return (a[prop] || 0) – (b[prop] || 0); }。

立即学习“Java免费学习笔记(深入)”;

a 和 b 是什么?在 sort() 方法的比较函数中,a 和 b 代表了 arr 数组中的两个元素,它们是待比较的完整对象。例如,如果 arr 是 [{ id: 3, value: 10 }, { id: 1, value: 5 }],那么 a 和 b 将依次是这些对象。

prop 是字符串,如何获取值?prop 参数是一个字符串,它代表了我们希望进行排序的对象属性的名称。在 JavaScript 中,我们可以使用方括号 [] 语法来通过字符串变量访问对象的属性,例如 a[prop]。如果 prop 的值为 “value”,那么 a[prop] 就等同于 a.value。这种动态属性访问是处理通用排序逻辑的关键。

(a[prop] || 0) – (b[prop] || 0) 的逻辑:

数值比较: 核心是 (aValue – bValue)。如果 aValue 小于 bValue,结果为负数,a 排在 b 前面;如果 aValue 大于 bValue,结果为正数,b 排在 a 前面;如果相等,结果为零。这正是 sort() 比较函数所期望的返回值行为。|| 0 处理 null/undefined: a[prop] || 0 是一种常见的 JavaScript 短路求值模式。如果 a[prop] 的值是 null、undefined、0、false 或空字符串,它将被视为“假值”,此时 || 运算符会返回 0。这意味着,如果对象的指定属性不存在或为 null/undefined,该属性的值将被视为 0 进行排序。这在处理数据不完整或可选属性时非常有用,确保了排序逻辑的健壮性。

因此,propSort 函数的整体逻辑是:遍历数组中的每对对象,取出它们指定属性的值(如果属性不存在或为 null 则默认为 0),然后进行数值比较,从而实现按该属性的升序排序。

TypeScript 转换与注意事项

将 propSort 函数转换为 TypeScript 可以显著提高代码的类型安全性、可读性和可维护性。转换的关键在于正确地定义输入数组的类型以及 prop 参数的类型。

/** * 根据对象数组中指定数值属性的值进行排序。 * null 或 undefined 的属性值将被视为 0。 * 数组元素必须是对象。 * @template T 数组中对象的类型。 * @param {T[]} arr - 要排序的对象数组。 * @param {keyof T} prop - 用于排序的数值属性名称。 */export const propSort = <T extends Record>(arr: T[], prop: keyof T): void => {    arr.sort((a, b) => {        // 确保属性值是可转换为数字的类型,并处理 null/undefined        const aValue = (a[prop] as unknown as number) || 0;        const bValue = (b[prop] as unknown as number) || 0;        return aValue - bValue;    });};

TypeScript 转换要点:

泛型 T: 我们引入了泛型 来代表数组 arr 中每个元素的类型。这使得 propSort 函数可以适用于任何类型的对象数组,提高了函数的通用性。T extends Record 约束 T 必须是一个对象类型。

arr: T[]: 明确 arr 是一个由 T 类型对象组成的数组。

prop: keyof T: 这是 TypeScript 中一个非常强大的类型工具。keyof T 会生成一个联合类型,包含 T 类型所有公共属性的字符串字面量。这意味着,当调用 propSort 时,prop 参数只能是 T 类型对象中实际存在的属性名,从而在编译时捕获拼写错误或不存在的属性访问,极大地增强了类型安全性。

类型断言 as unknown as number:

虽然 prop: keyof T 确保了 prop 是 T 的一个有效属性,但 TypeScript 无法静态地知道 T[prop] 的具体类型是否一定是 number。keyof T 只能保证属性存在,不保证其值类型。

因此,a[prop] 的类型在 TypeScript 中可能是 T[keyof T],这是一个宽泛的联合类型。为了能够进行数值减法,我们需要明确告诉 TypeScript 编译器,我们期望 a[prop] 和 b[prop] 的值最终能被当作 number 处理。

as unknown as number 是一个两阶段的类型断言。首先 as unknown 将类型转换为 unknown,这是一种安全的操作,表示我们不确定其类型。然后 as number 告诉编译器,我们确信它最终会是 number。这允许我们进行数值运算,但同时也意味着开发者需要确保运行时 a[prop] 的值确实可以被解释为数字,否则可能导致运行时错误(例如 NaN)。

更严谨的类型定义: 如果我们希望 prop 只能是 T 中 number 类型的属性,可以进一步约束 T 或 prop。例如:

type NumericPropertyKeys = {    [K in keyof T]: T[K] extends number | null | undefined ? K : never;}[keyof T];export const propSort = <T extends Record>(    arr: T[],    prop: NumericPropertyKeys): void => {    arr.sort((a, b) => {        const aValue = (a[prop] as number | null | undefined) || 0;        const bValue = (b[prop] as number | null | undefined) || 0;        return aValue - bValue;    });};

这种方式通过 NumericPropertyKeys 泛型类型,限制 prop 只能是 T 中类型为 number、null 或 undefined 的属性键,从而在编译时提供更强的类型检查。

注意事项:

运行时类型安全: 尽管 TypeScript 提供了编译时类型检查,但 (a[prop] as unknown as number) || 0 这样的断言并不能保证运行时 a[prop] 的值确实是数字。如果 a[prop] 是一个字符串(例如 “abc”),”abc” || 0 仍然是 “abc”,”abc” – (something) 会得到 NaN,导致排序结果不可预测。因此,在实际应用中,确保传入的数据结构符合预期至关重要,或者在比较函数内部增加更严格的运行时类型检查。原地排序: sort() 方法会修改原始数组。如果需要保留原始数组,应先创建数组的副本(例如 […arr].sort(…))。

总结

Array.prototype.sort() 结合自定义比较函数是 JavaScript 中实现复杂排序逻辑的强大工具。propSort 函数提供了一个简洁的模式,用于按对象指定数值属性进行排序,并优雅地处理了 null/undefined 值。将其转换为 TypeScript 后,通过泛型和 keyof 操作符,我们能够获得编译时的类型安全保障,避免常见的属性名拼写错误和类型不匹配问题,从而构建出更健壮、更易维护的代码。在实践中,合理运用 TypeScript 的类型系统,并辅以必要的运行时检查,可以最大限度地提升代码质量。

以上就是深入理解JavaScript对象数组按属性排序及其TypeScript实践的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1525215.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
动态替换HTML表格首行内容:无需ID的JavaScript实现
上一篇 2025年12月20日 17:29:26
JavaScript 的 RegExp 对象有哪些高级特性如正向否定断言?
下一篇 2025年12月20日 17:29:43

相关推荐

  • PPT幻灯片中怎么插入和编辑图表_PPT图表插入与数据可视化设置步骤

    PPT幻灯片中怎么插入和编辑图表_PPT图表插入与数据可视化设置步骤PPT幻灯片中怎么插入和编辑图表_PPT图表插入与数据可视化设置步骤PPT幻灯片中怎么插入和编辑图表_PPT图表插入与数据可视化设置步骤PPT幻灯片中怎么插入和编辑图表_PPT图表插入与数据可视化设置步骤

    插入图表可提升PPT信息传达效率。先打开PPT,点击“插入”选项卡中的“图表”,选择合适类型并确认,系统自动弹出Excel数据表供编辑,修改数据后关闭表格即可完成插入;双击图表可重新调整数据范围或更改图表类型,通过“图表设计”和“格式”选项卡优化样式、标题、图例及配色;为增强可视化效果,应保持简洁、…

    2026年10月3日 • 用户投稿
    000
  • OriginPC电脑黑屏问题如何处理?高端定制机故障诊断指南分享

    OriginPC电脑黑屏问题如何处理?高端定制机故障诊断指南分享OriginPC电脑黑屏问题如何处理?高端定制机故障诊断指南分享OriginPC电脑黑屏问题如何处理?高端定制机故障诊断指南分享OriginPC电脑黑屏问题如何处理?高端定制机故障诊断指南分享

    Origin PC电脑黑屏时电源灯亮,可能是显卡驱动、系统文件损坏或硬件冲突导致,需依次检查外部设备、显示器连接、电源供应,尝试BIOS重置、安全模式启动、更换显卡或内存条,若无效可重装系统,并联系Origin PC官网、客服电话、邮件支持或社区寻求帮助,平时应定期更新驱动、使用正版系统、安装杀毒软…

    2026年10月3日 • 用户投稿
    000
  • composer中的suggests有什么用_解析composer.json中suggests字段的用途

    composer中的suggests有什么用_解析composer.json中suggests字段的用途composer中的suggests有什么用_解析composer.json中suggests字段的用途composer中的suggests有什么用_解析composer.json中suggests字段的用途composer中的suggests有什么用_解析composer.json中suggests字段的用途

    suggests 是 composer.json 中的可选提示功能,用于推荐非必需的扩展包以增强项目功能,如日志、数据库操作或命令行工具支持;执行 composer install 或 update 时会显示建议列表,但不会自动安装这些包;与 require(必装)和 require-dev(开发依…

    2026年10月3日 • 用户投稿
    000
  • VSCode如何配置C++开发环境 VSCode搭建C++项目的完整教程

    VSCode如何配置C++开发环境 VSCode搭建C++项目的完整教程VSCode如何配置C++开发环境 VSCode搭建C++项目的完整教程VSCode如何配置C++开发环境 VSCode搭建C++项目的完整教程VSCode如何配置C++开发环境 VSCode搭建C++项目的完整教程

    首先安装c++++编译器和调试器,windows用户推荐mingw-w64并配置环境变量,macos用户安装xcode command line tools,linux用户通过包管理器安装gcc/g++和gdb;2. 安装vscode并添加c/c++扩展及可选的c/c++ extension pac…

    2026年10月3日 • 用户投稿
    600
  • 苹果15如何实现双微信功能

    一、利用第三方应用实现双开 想要在苹果15上运行两个微信,可以尝试从App Store中搜索并安装类似“微信分身版”这样的第三方工具。需要注意的是,这些应用并非腾讯官方推出,存在一定的使用风险,例如可能触发微信的安全机制导致账号被限制或封禁。安装完成后,打开该应用并按照指引完成第二个微信账号的登录。…

    2026年10月3日
    000
  • 在没有SSH权限的虚拟主机上如何使用composer?

    在没有SSH权限的虚拟主机上如何使用composer?在没有SSH权限的虚拟主机上如何使用composer?在没有SSH权限的虚拟主机上如何使用composer?在没有SSH权限的虚拟主机上如何使用composer?

    在无SSH权限的虚拟主机上使用Composer可通过本地或在线方式预生成依赖。1. 在本地安装Composer,创建composer.json,运行composer install生成vendor目录,并通过FTP上传vendor、composer.json和composer.lock文件至服务器。…

    2026年10月3日 • 用户投稿
    100
  • AcerSwift笔记本处理蓝屏代码0x00000078的步骤指南。

    AcerSwift笔记本处理蓝屏代码0x00000078的步骤指南。AcerSwift笔记本处理蓝屏代码0x00000078的步骤指南。AcerSwift笔记本处理蓝屏代码0x00000078的步骤指南。AcerSwift笔记本处理蓝屏代码0x00000078的步骤指南。

    蓝屏错误0x00000078通常因系统文件或驱动加载失败引起,可依次尝试安全模式诊断、运行SFC和CHKDSK修复系统与磁盘错误、更新驱动程序、执行系统还原及使用启动修复工具解决。 如果您的Acer Swift笔记本在使用过程中出现蓝屏,并显示错误代码0x00000078,这通常与系统启动时无法正确…

    2026年10月3日 • 用户投稿
    100
  • Notion AI新用户必看:5分钟上手基础写作与总结

    Notion AI新用户必看:5分钟上手基础写作与总结Notion AI新用户必看:5分钟上手基础写作与总结Notion AI新用户必看:5分钟上手基础写作与总结Notion AI新用户必看:5分钟上手基础写作与总结

    notion ai可通过掌握指令系统、使用模板、迭代优化、善用总结功能及认识局限性来快速生成高质量内容。首先熟悉基础指令并自定义以适应不同写作风格;其次从预设模板入手了解应用场景;随后对ai生成内容进行多次修改优化;利用ai总结功能提取关键信息;同时注意核实事实避免错误。针对博客写作,需结合选题研究…

    2026年10月3日 • 用户投稿
    000
  • win11连接不上蓝牙耳机怎么办_蓝牙设备连接失败修复指南

    win11连接不上蓝牙耳机怎么办_蓝牙设备连接失败修复指南win11连接不上蓝牙耳机怎么办_蓝牙设备连接失败修复指南win11连接不上蓝牙耳机怎么办_蓝牙设备连接失败修复指南win11连接不上蓝牙耳机怎么办_蓝牙设备连接失败修复指南

    首先运行系统内置蓝牙疑难解答,若无效则检查并启动蓝牙支持服务,接着更新或重新安装蓝牙驱动程序,最后重置蓝牙适配器并重新配对设备。 如果您尝试在Windows 11系统中连接蓝牙耳机,但设备无法被发现或连接失败,可能是由于驱动问题、服务未启动或设置错误导致。以下是针对此问题的多种解决方案。 本文运行环…

    2026年10月3日 • 用户投稿
    100
  • Java字符串压缩算法优化:处理末尾字符序列的策略

    本文深入探讨了字符串压缩算法,旨在将连续重复字符替换为字符加计数。我们将分析在实现此类算法时常见的末尾字符序列处理遗漏问题,并提供一个优化后的Java解决方案,确保所有字符序列都能被正确压缩,从而实现如“abbbccccc”到“ab3c4”的准确转换。 理解字符串压缩需求 字符串压缩是一种常见的数据…

    2026年10月3日
    300
  • composer的config命令常用配置项详解

    composer的config命令常用配置项详解composer的config命令常用配置项详解composer的config命令常用配置项详解composer的config命令常用配置项详解

    Composer config 命令用于管理项目配置,如仓库源、缓存路径、认证信息等。1. repositories 可添加私有仓库或镜像源;2. home 设置全局存储目录;3. cache-dir 指定缓存路径;4. http-basic 配置私有仓库认证;5. autoloader-suffi…

    2026年10月3日 • 用户投稿
    100
  • win10夜间模式打不开怎么办_Win10夜间模式开关灰色无法启用的修复方法

    win10夜间模式打不开怎么办_Win10夜间模式开关灰色无法启用的修复方法win10夜间模式打不开怎么办_Win10夜间模式开关灰色无法启用的修复方法win10夜间模式打不开怎么办_Win10夜间模式开关灰色无法启用的修复方法win10夜间模式打不开怎么办_Win10夜间模式开关灰色无法启用的修复方法

    如果您尝试在Windows 10中启用夜间模式,却发现该功能开关呈现灰色且无法点击,这通常与系统服务、显卡驱动或相关设置异常有关。以下是解决此问题的具体步骤: 本文运行环境:Dell XPS 13,Windows 10 专业版 一、检查并启动必要系统服务 夜间模式依赖于特定的后台服务运行,若这些服务…

    2026年10月3日 • 用户投稿
    200
  • 如何从坏掉的SSD中恢复数据?借助专业工具提取固态硬盘数据

    如何从坏掉的SSD中恢复数据?借助专业工具提取固态硬盘数据如何从坏掉的SSD中恢复数据?借助专业工具提取固态硬盘数据如何从坏掉的SSD中恢复数据?借助专业工具提取固态硬盘数据如何从坏掉的SSD中恢复数据?借助专业工具提取固态硬盘数据

    发现SSD无法识别或读取失败时,应立即停用并断开连接,通过磁盘管理判断损坏类型;若为逻辑故障,使用嗨格式数据恢复大师等专业软件深度扫描并以只读模式挂载避免覆盖;若为物理损坏如主控或闪存故障,需送至配备PC-3000 Flash等设备的专业机构进行芯片级恢复,成本通常超2000元。 如果您发现SSD无…

    2026年10月3日 • 用户投稿
    100
  • 抖音主播怎么创建粉丝群?抖音如何创建粉丝群

    抖音已成为众多主播展示才华、积累粉丝的重要平台。而粉丝群作为主播与粉丝互动的关键渠道,正逐渐成为社群营销的新热点。那么,抖音主播如何创建粉丝群,打造高效的社群营销阵地呢?本文将从多个角度详细说明。 一、粉丝群的优势不容忽视 提升粉丝黏性粉丝群为主播提供了一个与粉丝深度互动的空间,通过日常交流和分享,…

    2026年10月3日
    100
  • Self Forcing— Adobe联合德克萨斯大学推出的视频生成模型

    Self Forcing— Adobe联合德克萨斯大学推出的视频生成模型Self Forcing— Adobe联合德克萨斯大学推出的视频生成模型Self Forcing— Adobe联合德克萨斯大学推出的视频生成模型Self Forcing— Adobe联合德克萨斯大学推出的视频生成模型

    self forcing 是由 adobe research 联合德克萨斯大学奥斯汀分校推出的全新自回归视频生成算法,旨在解决传统生成模型在训练与测试阶段存在的暴露偏差问题。该方法通过在训练过程中模拟自生成机制,以先前生成的帧作为条件生成后续帧,而非依赖真实帧,从而有效缩小了训练与测试分布之间的差异…

    2026年10月3日 • 用户投稿
    100
  • 谷歌浏览器怎么重置所有设置_谷歌浏览器恢复默认设置操作方法

    谷歌浏览器怎么重置所有设置_谷歌浏览器恢复默认设置操作方法谷歌浏览器怎么重置所有设置_谷歌浏览器恢复默认设置操作方法谷歌浏览器怎么重置所有设置_谷歌浏览器恢复默认设置操作方法谷歌浏览器怎么重置所有设置_谷歌浏览器恢复默认设置操作方法

    首先重置浏览器设置可解决运行异常问题。通过设置菜单选择“将设置还原为默认设置”并确认重置,适用于配置错误;若开发者工具异常,则在F12面板中点击“Restore defaults and reload”;若因配置文件损坏导致重置失败,需重命名“Default”文件夹以重建配置,或调整“Secure …

    2026年10月3日 • 用户投稿
    100
  • 显存差了4GB 玩家为何仍选择RTX 5070而非RX 9070:老外分析四大原因

    显存差了4GB 玩家为何仍选择RTX 5070而非RX 9070:老外分析四大原因显存差了4GB 玩家为何仍选择RTX 5070而非RX 9070:老外分析四大原因显存差了4GB 玩家为何仍选择RTX 5070而非RX 9070:老外分析四大原因显存差了4GB 玩家为何仍选择RTX 5070而非RX 9070:老外分析四大原因

    9月14日消息,amd的rx 9070虽然与nvidia rtx 5070定价相近,并拥有更大的显存容量和略微领先的游戏性能,但rtx 5070的市场销量依然大幅领先于rx 9070。 针对此现象,wccftech总结了四个关键原因。 DLSS 4生态更成熟,图像增强技术普及率更高 如今,图像超分技…

    2026年10月3日 • 用户投稿
    1700
  • win11控制面板在哪里打开_多种打开控制面板的路径

    win11控制面板在哪里打开_多种打开控制面板的路径win11控制面板在哪里打开_多种打开控制面板的路径win11控制面板在哪里打开_多种打开控制面板的路径win11控制面板在哪里打开_多种打开控制面板的路径

    1、通过Win+R输入control命令可快速启动控制面板;2、使用任务栏搜索“控制面板”并点击结果打开;3、在文件资源管理器地址栏输入“控制面板”或shell:ControlPanelFolder;4、在桌面创建控制面板快捷方式;5、从开始菜单的Windows工具文件夹中启动;6、在设置应用内搜索…

    2026年10月3日 • 用户投稿
    300
  • qq浏览器打印预览显示不全_qq浏览器打印预览显示不全问题解决方法

    qq浏览器打印预览显示不全_qq浏览器打印预览显示不全问题解决方法qq浏览器打印预览显示不全_qq浏览器打印预览显示不全问题解决方法qq浏览器打印预览显示不全_qq浏览器打印预览显示不全问题解决方法qq浏览器打印预览显示不全_qq浏览器打印预览显示不全问题解决方法

    1、调整打印预览缩放比例至“适合页面”或手动设为85%-90%;2、修改页边距为“无”或自定义为5mm;3、启用兼容性视图以修复老旧网页布局;4、安装高速渲染组件提升解析完整性;5、先另存为PDF再打印,确保内容完整。 如果您在使用QQ浏览器进行打印预览时发现页面内容显示不全,可能是由于页面缩放、边…

    2026年10月3日 • 用户投稿
    100
  • edge浏览器太占内存怎么办_edge浏览器内存占用过高优化方案

    edge浏览器太占内存怎么办_edge浏览器内存占用过高优化方案edge浏览器太占内存怎么办_edge浏览器内存占用过高优化方案edge浏览器太占内存怎么办_edge浏览器内存占用过高优化方案edge浏览器太占内存怎么办_edge浏览器内存占用过高优化方案

    1、通过重置Edge设置恢复默认状态可释放异常内存;2、迁移用户数据目录至非系统盘以减轻C盘压力并优化内存管理;3、禁用或移除高耗能扩展程序以降低资源占用;4、使用Shift+Esc打开任务管理器结束高内存占用进程,保持浏览器轻量化运行。 如果您发现Microsoft Edge浏览器运行时内存占用过…

    2026年10月3日 • 用户投稿
    200

发表回复

登录后才能评论
关注微信