2026年了,表格里点一下价格排序,10 块排到 2 块前面,是 sort 默认拿字符串在比吗?
结论先说:Array.prototype.sort 在不传比较函数时,会先把元素转成字符串,再按 UTF-16 码元逐位比较,所以 [2, 10, 1] 排出来常见结果是 [1, 10, 2],10 排在 2 前面既不是浏览器出错,也不是 2026 年才冒出来的新坑,而是沿用已久的老规则。要按价格、库存、数量或日期排,就得显式传入比较函数,并把空值位置、是否原地修改、是否分页这几项写进验收口径,否则本地看着对、换一批数据又错。
默认比较做了什么,10 为什么排到 2 前面
默认排序分两步:先把每个元素转成字符串,再逐位比较 UTF-16 码元。数字 10 转成「10」,数字 2 转成「2」,逐位比较时首位「1」小于「2」,于是 10 被排到 2 前面。字符串形式的数字「10」和「2」结果一样,所以后端把数值字段以字符串返回时,同一类问题会反复出现。
这条规则不属于 ES6+ 新增特性,而是早期 JavaScript 继承下来的比较逻辑。ES2019 起规范要求排序稳定,但稳定只保证相等元素之间的相对顺序不变,并不改变默认的比较方式。判断要不要处理只有一条:排序字段是不是数值、金额、日期或带业务含义的编号。
- 默认排序可以接受:纯字母字符串的字典序、按约定展示的状态码。
- 默认排序不该用:价格、库存、销量、年龄、时间戳。
- 容易忽略:接口返回 null、undefined、空字符串时,默认行为会把它们排到一端,而业务未必希望如此。
交付现场:只排当前页,翻页后顺序就对不上
约束条件:一个大促活动列表,接口按页返回数据,每页 20 条,前端为了不等后端排期,先在本地对当前页按价格升序排。做法看起来省事,比较函数也写对了,本地自测通过。
上线后问题出现在第二页:用户把前两页连着看,发现整体价格并不是递增的,客服转来截图,业务方第一反应是数据错了。代价是返工约 0.5-1 人天,还多走了一次提测,前端把比较函数删掉,改成把排序字段和方向作为接口参数传回服务端。后来团队在联调单里固定加一行「排序字段类型 + 是否服务端排序 + 空值置顶还是置底」,这类返工基本没再出现。按经验区间,这类本地补丁的返工量通常落在半天到两天之间,取决于是否已经上线。
这段经历里最值钱的不是比较函数怎么写,而是提前问一句:这份数据是不是全量。分页、无限滚动、多端共用这三类场景,本地排序再准也只能排眼前这一段。
默认排序、前端显式比较、服务端排序怎么取舍
三种做法不是替代关系,而是按数据量和一致性要求分工。2026 年常见做法是:一次拿全、条数有限的展示列表放前端排;分页、多端共用、规则会变的列表交给服务端。下面按成本与适用面做一组可核对的对比,均为经验区间,具体以字段和索引情况为准。
- 默认排序:开发成本接近零,只适合纯字符串字典序展示;不适合金额、数量、日期,也不适合需要写进接口文档的业务顺序。
- 前端显式比较函数:开发加自测常见 0.5-2 小时,适合几百到几千条、已一次性拿到本地的数据;代价是要额外处理空值归一化和原数组复制。
- 服务端排序:接口改造经验区间多在 0.5-2 人天,视字段与索引而定,适合分页、大数据量、多端一致;代价是依赖后端排期,联调链路更长。
比较函数本身有几条底线:数字用 (a, b) => a - b,不要写成返回布尔值的 a > b;日期先转时间戳再相减;中文名称需要稳定语序时用 localeCompare 并显式指定 locale,且要在目标环境里核对,不能只看开发机结果。
哪些情况适合前端本地排,哪些不该碰
判断标准不是前端能不能写,而是排序结果是否要跨页、跨端、跨角色保持一致。
- 适合:数据一次性全量返回,条数在几百到几千以内;排序只影响当前视图,不写回接口,也不作为导出或报表依据;规则简单稳定,比如按名称、按约定展示顺序。
- 不适合:分页或无限滚动列表,前端只看到局部数据;金额、库存、销量这类会直接影响用户决策的字段;Web、小程序、App 三端要一致顺序;排序规则还在频繁调整。
- 介于两者之间:条数不大但字段含空值,可以先归一化再在前端排,前提是把空值位置写进验收清单,而不是留给默认行为。
常见问题
[10, 2, 1].sort() 出来为什么是 [1, 10, 2]?
因为默认排序先把元素转成字符串再逐位比较,「10」的首位「1」小于「2」,所以 10 排在前面;要按数值排,传入比较函数即可。
比较函数返回 true 或 false 行不行?
不行。比较函数要返回负数、0 或正数,返回布尔值会被当成 0 或 1 参与比较,结果依赖引擎实现,换一批数据就容易乱。
sort 会改原数组吗?
会,sort 是原地排序。需要保留原数组时先复制再排,常用扩展运算符或 slice,否则可能改到其他组件共用的筛选数据。
数字排序只写 a - b 就够了吗?
常规数字够用。数据里若有 NaN、null、undefined 或空字符串,要先归一化或单独写空值置顶置底规则,否则结果未必符合业务预期。
下次遇到列表顺序不对,先确认排序字段类型和数据是否分页,再看有没有传比较函数,最后把空值位置与多列优先级写进验收清单。适用边界:前端本地排序只适合一次性拿到全量、条数有限、且不要求跨端一致的展示列表;分页、金额类和多端共用场景交给服务端排序,成本按经验区间评估,不要拿默认排序兜底。
-
2026年了,React 后台上午还挺顺,下午进几趟详情页就卡,重启浏览器又好了,是监听和定时器没还回去吗?
日期:2026年11月1日 阅读:65
-
2026年了,弹窗里点“获取验证码”,整张表单也跟着提交了,是按钮默认 type 在作怪吗?
日期:2026年10月30日 阅读:32
-
2026年了,AI 把官网首页出得挺快,目标机型上一开就图片错位、按钮点不到,兼容和性能这摊还该前端收吗?
日期:2026年10月29日 阅读:66
-
2026年了,述职被问前端体验架构师和普通前端差在哪,我拿什么证明才算数?
日期:2026年10月28日 阅读:42
-
2026年了,活动页倒计时锁屏几分钟再打开就慢了一大截,用户截图问是不是我们少给了时间,问题出在哪?
日期:2026年10月27日 阅读:108




