JavaScript 排序完全指南:从基础到高阶实战

排序是数据处理的核心操作,JavaScript 提供了多种灵活的方式实现数组排序。本文将从内置方法 、经典算法 、高级技巧三个维度展开,并附代码示例与性能对比,助你彻底掌握排序技术。

🔧 一、基础:内置 Array.prototype.sort()

JavaScript 的 sort() 是原地排序方法 (直接修改原数组),默认按 Unicode 编码将元素转为字符串后排序。但通过自定义比较函数,可轻松实现复杂逻辑。

1. 数值排序

javascript

复制代码

// 升序

const numbers = [10, 2, 5];

numbers.sort((a, b) => a - b); // [2, 5, 10]

// 降序

numbers.sort((a, b) => b - a); // [10, 5, 2]

2. 字符串排序

javascript

复制代码

// 忽略大小写

const fruits = ["Banana", "apple", "Cherry"];

fruits.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));

// ["apple", "Banana", "Cherry"]

3. 对象数组排序

按对象属性排序是常见需求:

javascript

复制代码

const users = [

{ name: "Alice", age: 30 },

{ name: "Bob", age: 25 }

];

users.sort((a, b) => a.age - b.age); // 按年龄升序

⚙️ 二、经典排序算法实现

虽然 sort() 足够强大,但理解底层算法有助于优化性能。以下是三种常用手写排序算法:

1. 冒泡排序

时间复杂度:O(n²)

适用场景:小型数组或教学演示

javascript

复制代码

function bubbleSort(arr) {

for (let i = 0; i < arr.length - 1; i++) {

for (let j = 0; j < arr.length - 1 - i; j++) {

if (arr[j] > arr[j + 1]) {

[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 交换相邻元素

}

}

}

return arr;

}

2. 快速排序

时间复杂度:平均 O(n log n)

适用场景:大数据量、高性能需求

javascript

复制代码

function quickSort(arr) {

if (arr.length <= 1) return arr;

const pivot = arr[Math.floor(arr.length / 2)];

const left = arr.filter(x => x < pivot);

const right = arr.filter(x => x > pivot);

return [...quickSort(left), pivot, ...quickSort(right)];

}

3. 插入排序

时间复杂度:O(n²)

适用场景:近乎有序的小数组

javascript

复制代码

function insertionSort(arr) {

for (let i = 1; i < arr.length; i++) {

const current = arr[i];

let j = i - 1;

while (j >= 0 && arr[j] > current) {

arr[j + 1] = arr[j];

j--;

}

arr[j + 1] = current;

}

return arr;

}

🚀 三、高级排序技巧

1. 多字段排序

当主排序字段相同时,按次字段排序:

javascript

复制代码

const employees = [

{ name: "Alice", age: 30, role: "Developer" },

{ name: "Bob", age: 30, role: "Designer" }

];

employees.sort((a, b) => {

// 先按年龄升序,年龄相同按角色字母排序

return a.age - b.age || a.role.localeCompare(b.role);

});

2. 稳定排序的重要性

ES2019 后 sort() 是稳定排序,即相同键值的元素保持原始顺序:

javascript

复制代码

const items = [

{ id: 1, type: 'fruit' },

{ id: 2, type: 'vegetable' },

{ id: 3, type: 'fruit' }

];

// 按 type 排序后,id=1 和 id=3 的 "fruit" 相对顺序不变

3. 洗牌算法(随机排序)

使用 Fisher-Yates 算法高效打乱数组:

javascript

复制代码

function shuffle(arr) {

for (let i = arr.length - 1; i > 0; i--) {

const j = Math.floor(Math.random() * (i + 1));

[arr[i], arr[j]] = [arr[j], arr[i]];

}

return arr;

}

4. 性能优化:映射排序(大数组)

对复杂对象数组,可先映射关键值再排序,减少计算:

javascript

复制代码

const products = [

{ name: "Laptop", price: 1200 },

{ name: "Phone", price: 800 }

];

// 1. 创建价格映射

const priceMap = new Map(products.map(p => [p, p.price]));

// 2. 排序

products.sort((a, b) => priceMap.get(a) - priceMap.get(b));

📊 四、排序方法性能对比

方法

时间复杂度

适用场景

稳定性

sort()

各引擎优化(如快排)

通用场景

冒泡排序

O(n²)

教学/小数组

快速排序

O(n log n) 平均

大数据量

不稳定

插入排序

O(n²)

近乎有序的小数组

💡 建议:

90% 场景使用内置 sort() + 自定义比较函数即可。

大数组(>10k 元素)优先选择分治类算法(如快速排序)。

对稳定性有要求时(如表格多级排序),确认环境支持 ES2019+。

💎 总结

JavaScript 排序既灵活又强大:

基础 :掌握 sort() 的比较函数写法,解决数值、字符串、对象排序问题。

进阶:理解经典算法原理,根据场景选择最优解。

高阶:多字段排序、洗牌算法、性能优化提升实战能力。