sort() 默认将元素转为字符串并按 Unicode 码点排序,非数值顺序;比较函数需返回正负零三值,避免布尔返回;对象排序要处理 null/undefined;多级排序需嵌套判断;sort() 会修改原数组且比较函数须为纯函数。

sort() 默认排序行为是什么?
sort() 不传参数时,会把数组元素转成字符串再按 Unicode 码点排序,不是数值大小顺序。这意味着 [10, 2, 33, 1] 会变成 [1, 10, 2, 33],因为 "10" 为 true。
- 仅适用于字符串数组(如
["banana", "apple", "cherry"]) - 数字数组必须传比较函数,否则结果不符合直觉
- 原地修改数组,不返回新数组
数值升序和降序怎么写比较函数?
比较函数接收两个参数 a 和 b,返回负数、0 或正数来决定顺序。常见写法:
const nums = [10, 2, 33, 1];// 升序:a - b nums.sort((a, b) => a - b); // [1, 2, 10, 33]
// 降序:b - a nums.sort((a, b) => b - a); // [33, 10, 2, 1]
- 用
a - b而不是a > b,因为后者只返回布尔值,无法表达“相等”或“大小关系强度” - 避免写
return a > b ? 1 : -1,它漏掉相等情况,会导致排序不稳定或异常 - 浮点数、
NaN参与运算时需额外判断(NaN - 5是NaN,会破坏排序逻辑)
对象数组按某个字段排序怎么写?
用属性访问 + 数值或字符串比较。注意处理 undefined 或 null 值,否则可能触发 Cannot read property 'xxx' of undefined 错误。
const users = [
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 35 }
];
// 按 age 升序
users.sort((a, b) => (a.age || 0) - (b.age || 0));
// 按 name 字母序(忽略大小写)
users.sort((a, b) => a.name.localeCompare(b.name));
-
localeCompare()比a.name > b.name更可靠,支持中文、重音字符等 - 字段缺失时用
a.prop ?? ""或a.prop || ""提供默认值,防止undefined参与比较 - 如果要多级排序(如先按
age,年龄相同时按name),在第一个比较返回 0 时继续第二个比较
sort() 的稳定性与副作用要注意什么?
ES2019 起,sort() 在大多数引擎中是稳定排序(相同值的相对位置不变),但不能依赖这点做关键逻辑。更实际的风险是:
立即学习“Java免费学习笔记(深入)”;
- 直接对引用类型数组排序会改变原数组,若需保留原始顺序,先用
[...arr].sort(...)或arr.slice().sort(...) - 在比较函数里修改
a或b的属性,可能导致不可预期的结果(比如排序中途改变了用于比较的值) - 异步操作、DOM 读取等副作用写在比较函数里是危险的——
sort()调用时机和次数由引擎决定,不可控
真正容易被忽略的是:比较函数必须是纯函数。哪怕只是 console.log() 都可能干扰性能分析或导致调试混淆。











