把一组数字交给 JavaScript 的 sort(),10 却排到了 2 前面。问题不在于排序随机失效,而在于没有告诉普通数组按数值比较。
这次在 Node.js v22.23.1 中跑了一段独立样例。它只是普通有限数字的局部实验,不是生产数据测试,也不代表其他排序对象的规则。
同一份输入,默认排序和数值排序不同
const values = [2, 10, 1]; console.log([...values].sort()); // [1, 10, 2] console.log([...values].sort((a, b) => a - b)); // [1, 2, 10]
两种实际输出如上。样例先展开成新数组再排序,原来的 values 仍是 [2, 10, 1],方便对照同一份输入。
没有比较函数,不等于自动识别数字
ECMAScript 的 CompareArrayElements 算法规定:在没有提供比较函数、且走到普通值比较步骤时,会把两项转换成字符串后比较。[5]
因此这个例子比较的是字符串形式的“1”“10”“2”,而不是数值大小。结果中的元素依然是数字;参与比较时做转换,不等于把存储的元素全部改成字符串。
给出 (a, b) => a - b 后,这组有限数字才按数值升序排列。这里表达的是先后关系,不是简单返回“是否更大”的布尔值。
把比较规则写成输入合同
我的判断是:遇到排序结果不合预期,先问“按什么比较”,而不是先怀疑语言或引擎。数量按数值、标题按文本、对象按哪个字段,应当明确区分。
这个短写法只针对本例这样的普通有限数字。如果输入混有字符串、空值或 NaN,先明确清洗和缺失值策略;不要把它当成所有数组的万能排序函数。本文也不把普通 Array 的默认规则推广到 TypedArray。
数字放在数组里,并不会让默认比较规则自动变成数值比较。对读者来说,最小修正不是换工具,而是把所需顺序写清楚。
资料核验与样例执行:2026年10月22日。本文由 AI 辅助整理。