js Array sort实战排序全面讲解教程

 更新时间:2026年01月20日 08:30:28   作者:书签篮  
在JavaScript中Array对象提供了sort方法,用于对数组元素进行排序,这篇文章主要介绍了js Array sort实战排序的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、sort()方法基础认知

1. 基本定义

sort() 是 JavaScript 数组原型上的内置方法,用于对数组元素进行排序,并返回排序后的原数组(注意:它是「原地排序」,会直接修改原始数组,而非返回新数组)。

2. 默认排序规则

sort() 方法如果不传入任何参数,会按照「字符串 Unicode 编码」进行排序,而非我们直觉中的数字大小排序,这是新手最容易踩坑的点。

示例:默认排序的表现

// 1. 字符串数组(符合直觉,按Unicode排序)
const strArr = ["banana", "apple", "cherry", "Abc"];
strArr.sort();
console.log(strArr); // ["Abc", "apple", "banana", "cherry"]
// 原因:Unicode 中大写字母编码(A-Z:65-90)小于小写字母(a-z:97-122)

// 2. 数字数组(不符合直觉,按字符串Unicode排序)
const numArr = [10, 2, 31, 4, 25];
numArr.sort();
console.log(numArr); // [10, 2, 25, 31, 4]
// 原因:数字会被先转为字符串,"10"的Unicode编码小于"2",因此10排在2前面

二、sort()核心:比较函数(compareFunction)

要实现按数字大小、对象属性等自定义规则排序,必须给 sort() 传入一个比较函数((a, b) => {},这是 sort() 方法的灵魂。

1. 比较函数的参数与返回值规则

比较函数接收两个必选参数 ab(代表数组中任意两个待比较的元素,a 是后一个元素,b 是前一个元素),返回值的类型决定了排序结果:

比较函数返回值排序规则
返回 负数< 0a 排在 b 前面(升序逻辑)
返回 0ab 位置不变(稳定排序的关键)
返回 正数> 0a 排在 b 后面(降序逻辑)

2. 数字数组的正/降序排序(最常用场景)

(1)数字升序排序

const numArr = [10, 2, 31, 4, 25];
// 比较函数:a - b 实现升序
numArr.sort((a, b) => a - b);
console.log(numArr); // [2, 4, 10, 25, 31]
// 原理:若a < b,a - b为负数,a排在b前面;若a > b,a - b为正数,a排在b后面

(2)数字降序排序

const numArr = [10, 2, 31, 4, 25];
// 比较函数:b - a 实现降序
numArr.sort((a, b) => b - a);
console.log(numArr); // [31, 25, 10, 4, 2]
// 原理:若b > a,b - a为正数,a排在b后面(即大的数排在前面)

三、常见场景实战排序

1. 字符串数组:忽略大小写排序

默认排序会区分大小写,通过将元素统一转为大写/小写后比较,可实现忽略大小写的排序:

const strArr = ["banana", "Apple", "cherry", "abc"];
strArr.sort((a, b) => {
  const lowerA = a.toLowerCase();
  const lowerB = b.toLowerCase();
  if (lowerA < lowerB) return -1; // 升序
  if (lowerA > lowerB) return 1;
  return 0;
});
console.log(strArr); // ["Apple", "abc", "banana", "cherry"]

2. 字符串数组:按长度排序

const strArr = ["banana", "apple", "cherry", "a"];
// 先按长度升序,长度相同按Unicode升序
strArr.sort((a, b) => {
  if (a.length !== b.length) {
    return a.length - b.length; // 长度升序
  }
  return a.localeCompare(b); // 长度相同,按自然语言排序(比直接比较字符串更友好)
});
console.log(strArr); // ["a", "apple", "banana", "cherry"]

3. 对象数组:按单个属性排序

日常开发中最常用的场景,比如按用户年龄、商品价格排序:

// 用户数组
const users = [
  { name: "张三", age: 25, salary: 8000 },
  { name: "李四", age: 20, salary: 10000 },
  { name: "王五", age: 30, salary: 7000 },
];

// (1)按年龄升序排序
users.sort((a, b) => a.age - b.age);
console.log(users.map(u => u.name)); // ["李四", "张三", "王五"]

// (2)按薪资降序排序
users.sort((a, b) => b.salary - a.salary);
console.log(users.map(u => u.name)); // ["李四", "张三", "王五"]

// (3)按姓名自然语言排序(中文排序)
users.sort((a, b) => a.name.localeCompare(b.name, "zh-CN"));
console.log(users.map(u => u.name)); // ["李四", "王五", "张三"]

4. 对象数组:多条件排序

当第一个排序条件相同时,按第二个条件排序(比如:先按年龄升序,年龄相同按薪资降序):

const users = [
  { name: "张三", age: 25, salary: 8000 },
  { name: "李四", age: 20, salary: 10000 },
  { name: "赵六", age: 25, salary: 9000 },
  { name: "王五", age: 30, salary: 7000 },
];

users.sort((a, b) => {
  // 第一个条件:年龄升序
  if (a.age !== b.age) {
    return a.age - b.age;
  }
  // 第二个条件:薪资降序(年龄相同时生效)
  return b.salary - a.salary;
});

console.log(users.map(u => `${u.name}(${u.age}岁,${u.salary}元)`));
// 输出:
// ["李四(20岁,10000元)", "赵六(25岁,9000元)", "张三(25岁,8000元)", "王五(30岁,7000元)"]

5. 包含特殊值(null/undefined)的数组排序

sort() 会自动将 undefined 排到数组末尾;null 转为数字是 0,可手动处理其排序位置:

const mixedArr = [10, null, 5, undefined, 3, null, 8];
mixedArr.sort((a, b) => {
  // 处理undefined:直接排到末尾
  if (a === undefined) return 1;
  if (b === undefined) return -1;
  // 处理null:按0参与数字升序排序
  return (a ?? 0) - (b ?? 0);
});
console.log(mixedArr); // [null, null, 3, 5, 8, 10, undefined]

四、进阶知识点:稳定排序

1. 稳定排序的定义

如果数组中两个相等的元素(按比较函数判断返回 0),在排序前后的相对位置保持不变,这种排序就是「稳定排序」。

2.sort()的稳定性

  • ES6(ECMAScript 2015)及以后:sort() 方法实现了稳定排序(不同浏览器内核实现一致)。
  • ES6 之前:sort() 是不稳定排序,不同浏览器表现可能不同。

示例:验证稳定排序

// 商品数组:按价格升序(价格相同的商品,保持原有相对位置)
const goods = [
  { name: "商品A", price: 50 },
  { name: "商品B", price: 30 }, // 先出现
  { name: "商品C", price: 50 },
  { name: "商品D", price: 30 }, // 后出现
];

// 按价格升序排序
goods.sort((a, b) => a.price - b.price);

console.log(goods.map(g => g.name)); // ["商品B", "商品D", "商品A", "商品C"]
// 结果:价格30的商品B仍在商品D前面,价格50的商品A仍在商品C前面,验证了稳定排序

五、常见误区与避坑技巧

1. 误区1:忽略「原地排序」,误认返回新数组

sort() 会修改原始数组,返回的是原始数组的引用,而非新数组。如果需要保留原始数组,应先拷贝数组再排序。

避坑示例:

const originalArr = [10, 2, 31];
// 先拷贝数组(推荐使用扩展运算符或slice(),浅拷贝即可)
const sortedArr = [...originalArr].sort((a, b) => a - b);

console.log(originalArr); // [10, 2, 31](原始数组未被修改)
console.log(sortedArr); // [2, 10, 31](排序后的新数组)

2. 误区2:数字排序不传入比较函数

新手常直接对数字数组使用 sort(),导致排序结果不符合预期,必须传入 (a, b) => a - b(升序)或 (a, b) => b - a(降序)。

3. 误区3:比较函数返回非数字类型

比较函数的返回值应是数字(负数/0/正数),若返回布尔值或其他类型,会被隐式转为数字(true→1,false→0),可能导致排序异常。

错误示例 vs 正确示例:

const numArr = [10, 2, 31];

// 错误:返回布尔值,排序结果不可靠
numArr.sort((a, b) => a > b);

// 正确:返回数字,排序结果稳定
numArr.sort((a, b) => a - b);

4. 误区4:中文排序直接使用字符串比较

直接用 a > b 比较中文,会按 Unicode 编码排序,不符合中文的拼音/笔画排序逻辑,应使用 localeCompare() 并指定中文环境。

正确示例:中文拼音排序

const chineseArr = ["张三", "李四", "王五", "赵六"];
// localeCompare("zh-CN"):按中文拼音排序
chineseArr.sort((a, b) => a.localeCompare(b, "zh-CN"));
console.log(chineseArr); // ["李四", "王五", "张三", "赵六"]

六、sort()方法的性能说明

sort() 的底层排序算法并非固定(由浏览器内核实现):

  • Chrome/V8 引擎:对于小型数组(长度≤22)使用「插入排序」,大型数组使用「快速排序的变种(TimSort/QuickSort)」,平均时间复杂度为 O(n log n)
  • Firefox 引擎:使用「归并排序」,时间复杂度 O(n log n)
    日常开发中无需关注底层实现,只需关注排序规则和稳定性即可,其性能足以满足绝大多数业务场景。

总结

  1. sort() 是原地排序方法,会修改原始数组,需保留原数组时应先拷贝([...arr]/arr.slice())。
  2. 默认按字符串 Unicode 排序,数字/对象排序必须传入比较函数,核心规则是「返回负数a在前、返回正数a在后、返回0位置不变」。
  3. 常见场景:数字正/降序(a-b/b-a)、对象多条件排序、中文排序(localeCompare("zh-CN"))。
  4. ES6 及以后 sort() 是稳定排序,特殊值(undefined)默认排末尾,使用时需规避非数字返回值等误区。

到此这篇关于js Array sort实战排序全面讲解教程的文章就介绍到这了,更多相关js Array sort排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 用js实现每隔一秒刷新时间的实例(含年月日时分秒)

    用js实现每隔一秒刷新时间的实例(含年月日时分秒)

    下面小编就为大家带来一篇用js实现每隔一秒刷新时间的实例(含年月日时分秒)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 基于canvas实现的绚丽圆圈效果完整实例

    基于canvas实现的绚丽圆圈效果完整实例

    这篇文章主要介绍了基于canvas实现的绚丽圆圈效果,以完整实例形式分析了JavaScript结合html5的canvas实现动态图形的绘制技巧,需要的朋友可以参考下
    2016-01-01
  • JS前端的内存处理的方法全面详解

    JS前端的内存处理的方法全面详解

    这篇文章主要为大家介绍了JS前端的内存处理的方法全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • JS清除选择内容的方法

    JS清除选择内容的方法

    这篇文章主要介绍了JS清除选择内容的方法,较为详细的分析了js操作文本的技巧,需要的朋友可以参考下
    2015-01-01
  • JS实现漂亮的时间选择框效果

    JS实现漂亮的时间选择框效果

    这篇文章主要介绍了JS实现漂亮的时间选择框效果,结合实例形式分析了javascript时间选择框插件的实现与使用方法,需要的朋友可以参考下
    2016-08-08
  • 如何去除js中的json存在的转义字符\问题

    如何去除js中的json存在的转义字符\问题

    这篇文章主要介绍了如何去除js中的json存在的转义字符\问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • JS操作xml对象转换为Json对象示例

    JS操作xml对象转换为Json对象示例

    本篇文章主要介绍了JS操作xml对象转换为Json对象示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • 使用hasOwnProperty时报错的解决方法

    使用hasOwnProperty时报错的解决方法

    hasOwnProperty这个方法是用来查找一个对象是否有某个属性,且查找的属性必须是对象本身的一个成员,但是不会去查找对象的原型链,文中介绍了使用示例代码及使用时可能会遇到的问题,对hasOwnProperty报错原因分析及解决方法感兴趣的朋友一起看看吧
    2024-01-01
  • JavaScript读写二进制数据的方法详解

    JavaScript读写二进制数据的方法详解

    avascript里有两个内置对象,一个是ArrayBuffer;一个是DataView,读写二进制数据都需要使用这两个对象。这篇文章主要给大家介绍了关于JavaScript读写二进制数据的方法,需要的朋友可以参考下
    2018-09-09
  • JS获取屏幕高度的简单实现代码

    JS获取屏幕高度的简单实现代码

    下面小编就为大家带来一篇JS获取屏幕高度的实现代码。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05

最新评论