sort默认按字符串Unicode排序导致数字错乱;数字排序需传(a,b)=>a-b;对象按属性排序要处理undefined,字符串用localeCompare,多级排序用短路逻辑。
JavaScript 的 sort() 方法不传参时,会把数组元素先转成字符串,再按 Unicode 码点排序。这意味着 [10, 2, 33, 1] 会变成 [1, 10, 2, 33],因为 "10" 为 true。
这不是 bug,是设计如此 —— 它只保证“稳定比较”,不保证数值逻辑正确。
["banana", "apple", "cherry"]),默认行为可用null、undefined)在转换中会变成 "null" 或 "undefined",进一步扰乱顺序sort() 的比较函数接收两个参数 a 和 b,它只关心返回值的符号:
→ a 排在 b 前面
0 → a 和 b 位置不变(稳定排序)> 0 → a 排在 b 后面升序数字排序最简写法:
立即学习“Java免费学习笔记(深入)”;
numbers.sort((a, b) => a - b);
降序则反过来:
numbers.sort((a, b) => b - a);
注意:不能写 return a > b,那只会返回布尔值(true/false),被转成 1/0,导致排序错误或不稳定。
比如按 users 数组里的 age 升序排:
users.sort((a, b) => (a.age || 0) - (b.age || 0));
但更健壮的做法是显式处理缺失值,避免 undefined - 5 得到 NaN:
?? 提供默认值:(a.age ?? 0) - (b.age ?? 0)
users.filter(u => u.age != null).sort(...)
age 的项排最后,可写:return (a.age == null) - (b.age == null) || a.age - b.age;
字符串属性(如 name)建议用 localeCompare,支持大小写与本地化:
users.sort((a, b) => a.name.localeCompare(b.name));
要先按 status('active' > 'pending' > 'archived'),再按 createdAt 时间倒序,别这么写:
if (a.status !== b.status) { return ... } else { return ... }而是用「短路」逻辑,一行搞定:
items.sort((a, b) => {
const statusOrder = { active: 0, pending: 1, archived: 2 };
const byStatus = (statusOrder[a.status] || 99) - (statusOrder[b.status] || 99);
return byStatus || new Date(b.createdAt) - new Date(a.createdAt);
});关键点:
|| 继续下一项Date 对象,否则字符串时间(如 "2025-01-01")仍走字典序[...arr].sort(...) 避免副作用sort 的比较函数看似简单,但边界情况(null、NaN、时区、Unicode)最容易漏掉。每
次写之前,先问一句:这个 a 和 b 可能是什么值?