前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库数组 sort 默认字符串 Unicode 排序
JSJavaScript数组与集合

数字数组直接 sort 为什么会把 10 排在 9 前面?

数组里装着数字,并不会让普通 Array.sort 自动切换到数值大小比较。

前端进阶之旅 · 一题精讲更新于 2026.09.06
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

拆开排序的三个决定

  1. 取比较键元素本身、字段或规范化后的业务值
  2. 比较关系返回负数、零或正数表达顺序
  3. 保存结果决定是否允许修改原数组容器

默认顺序按 UTF-16 码元比较,不能笼统等同于 Unicode 码点顺序或按用户语言习惯排序。

核心回答

先记住这个答案

普通数组 sort 没有比较函数时,会把参与比较的非 undefined 元素转成字符串,再按 UTF-16 码元序列比较。字符串 "10" 的首位比 "9" 小,所以十可以排在九前面。已确认是普通有限 Number 的数组做升序时,可提供 (a, b) => a - b,比较器返回值的负、零、正分别表示前后或相等关系。sort 会修改原数组,默认字符串顺序也不是人类语言排序。混合类型、NaN、对象或特殊业务值应先明确排序键和无效值策略,不能无条件套减法。

  • 默认比较按字符串而非数字大小
  • 比较器看返回符号,不是布尔真假
  • sort 修改原数组,排序键与缺失值需明确

相同输入只替换比较函数

下面分别在副本上做默认排序和数值升序,让源数组保持不变。二十的字符串首位也会影响默认结果,说明这不是十和九的特殊例外,而是比较键发生了变化。

示例使用已知有限数字,减法可以清楚表达数值大小关系。复制只是为了隔离 sort 的原地副作用,不代表排序会深拷贝对象,也不能作为所有数据都适用该比较器的证据。

默认字符串顺序与数值顺序JavaScript
const values = [10, 9, 20, 2];
console.log(JSON.stringify([...values].sort()));
console.log(JSON.stringify([...values].sort((a, b) => a - b)));
console.log(JSON.stringify(values));
查看输出与解释
[10,2,20,9]
[2,9,10,20]
[10,9,20,2]

默认比较把十、二、二十、九按字符串序列排列,数值比较器得到正常升序。源数组未变来自先创建副本,若直接 values.sort 则会修改它。

比较器必须表达一致的顺序关系

返回 a > b 只有 true 和 false,转换后缺少负数方向,无法完整表达一项应排在另一项之前。比较器应尽量纯粹,对同一对输入给出一致结果,并遵守合理的反对称与传递关系。

若元素是业务记录,应先选择 price、createdAt 等明确键,并处理相同键的次级规则。不要在比较回调中修改记录或依赖不断变化的外部状态,否则算法调用顺序会把结果变得难以解释。

缺失值、NaN 和本地化需要专门策略

减法遇到 NaN 可能产生无法表达预期顺序的返回值,混合字符串或空值也可能发生意外转换。应先校验输入,或明确无效值排前、排后、拒绝排序等策略,再编写比较器。

用户姓名、带数字的产品名或不同语言文本,可能需要 Intl.Collator 等本地化比较能力。排序稳定只表示比较相等时保留原相对顺序,不会把默认字符串比较自动修正为业务想要的数值或语言规则。

回答前,多想一步

容易答错的地方

认为稳定排序就能保证数字大小正确
稳定性只约束比较器认为相等的元素之间的相对次序,不改变默认比较规则。数值升序仍需明确数值比较器,并验证缺失或无效数据的处理,不能用一个算法性质替代业务排序定义。
比较器返回布尔值就觉得足够
布尔值只能提供零和一,不能完整表示负方向,容易违反顺序关系要求。应返回能区分前、后和相等的数值,并使用相反输入顺序及相等键测试检查一致性。
试着用自己的话回答

面试官还会怎么问?

对象数组直接 sort 会按某个字段吗?

不会自动知道业务字段,默认转换得到的字符串通常也不适合业务顺序。应显式提取排序键并定义缺失值与相同键策略,避免依赖对象默认字符串表示。

sort 与 toSorted 如何选择?

sort 修改当前数组,toSorted 在支持它的环境里提供复制后排序的接口。二者都需要正确比较规则,是否复制容器与怎样比较元素是独立选择,同时应检查目标运行环境支持。

数字字符串能直接用减法比较吗?

可能触发数值转换,但应先确认字符串确实满足业务数值格式,空字符串、非法文本和精度范围都需要处理。显式解析与校验能让失败更清楚,不能把隐式转换当作完整输入验证。

从一道题,走向一组知识

把知识连起来

数组与集合

Array.prototype.sort 会修改原数组吗?如果不想修改原数组该怎么做?

明确排序容器是否允许原地改变并选择复制方案。

数组与集合

Array.isArray 与 instanceof Array 有什么区别,跨 iframe 为什么会失效?

在排序前先确认输入容器身份与元素校验范围。

参考资料

  • MDN:sort

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 相同输入只替换比较函数
  3. 比较器必须表达一致的顺序关系
  4. 缺失值、NaN 和本地化需要专门策略
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑