JavaScript 数组 .sort() 方法详解 🎯

🔍 基本语法

array.sort([compareFunction])

🚀 基本使用

默认排序(字符串排序)

const fruits = ['banana', 'apple', 'cherry', 'date'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'cherry', 'date']

const numbers = [10, 2, 1, 20, 5];
numbers.sort();
console.log(numbers); // [1, 10, 2, 20, 5] ❌ 不是数值顺序!

🔧 比较函数详解

比较函数规则

function compare(a, b) {
    if (a < b) return -1;  // a 排在 b 前面
    if (a > b) return 1;   // a 排在 b 后面
    return 0;              // 位置不变
}

数值排序

const numbers = [10, 2, 1, 20, 5];

// ✅ 升序排序
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 5, 10, 20]

// ✅ 降序排序  
numbers.sort((a, b) => b - a);
console.log(numbers); // [20, 10, 5, 2, 1]

📊 各种排序示例

对象数组排序

const students = [
    { name: 'Alice', score: 85 },
    { name: 'Bob', score: 92 },
    { name: 'Charlie', score: 78 }
];

// 按分数升序
students.sort((a, b) => a.score - b.score);

// 按分数降序
students.sort((a, b) => b.score - a.score);

// 按名字字母顺序
students.sort((a, b) => a.name.localeCompare(b.name));

字符串排序(支持中文)

const names = ['张三', '李四', '王五', 'Alice', 'Bob'];

// 简单字母排序
names.sort();

// 国际化排序
names.sort((a, b) => a.localeCompare(b, 'zh-CN'));

// 忽略大小写排序
const mixedCase = ['apple', 'Banana', 'cherry'];
mixedCase.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));

多条件排序

const products = [
    { name: 'Laptop', price: 1000, rating: 4.5 },
    { name: 'Phone', price: 500, rating: 4.2 },
    { name: 'Tablet', price: 500, rating: 4.7 }
];

// 先按价格升序,再按评分降序
products.sort((a, b) => {
    if (a.price !== b.price) {
        return a.price - b.price;
    }
    return b.rating - a.rating;
});

⚠️ 重要特性

原地排序(修改原数组)

const arr = [3, 1, 2];
const sorted = arr.sort();

console.log(arr);    // [1, 2, 3] ❌ 原数组被修改!
console.log(sorted); // [1, 2, 3]
console.log(arr === sorted); // true

保持引用关系

const original = [{x: 3}, {x: 1}, {x: 2}];
const sorted = original.sort((a, b) => a.x - b.x);

console.log(original[0] === sorted[0]); // true ✅ 对象引用不变

🛡️ 安全排序模式

创建副本再排序

const arr = [3, 1, 2];

// ✅ 安全排序(不修改原数组)
const sorted = [...arr].sort((a, b) => a - b);
// 或者
const sorted2 = arr.slice().sort((a, b) => a - b);

console.log(arr);    // [3, 1, 2] ✅ 原数组不变
console.log(sorted); // [1, 2, 3]

🎯 高级排序技巧

随机排序

const array = [1, 2, 3, 4, 5];

// 随机打乱数组
array.sort(() => Math.random() - 0.5);
console.log(array); // 随机顺序,如 [3, 1, 5, 2, 4]

自定义排序规则

const priorities = ['高', '中', '低'];
const tasks = [
    { title: '任务A', priority: '中' },
    { title: '任务B', priority: '高' },
    { title: '任务C', priority: '低' }
];

// 按自定义优先级排序
tasks.sort((a, b) => {
    return priorities.indexOf(a.priority) - priorities.indexOf(b.priority);
});

稳定排序模拟

// 保持相同元素的原始顺序
function stableSort(array, compare) {
    return array
        .map((item, index) => ({ item, index }))
        .sort((a, b) => compare(a.item, b.item) || a.index - b.index)
        .map(entry => entry.item);
}

🔄 性能优化

预计算优化

// 对于复杂计算,可以预计算排序键
const items = [/* 大量数据 */];

// 预计算排序键
const itemsWithKey = items.map(item => ({
    original: item,
    sortKey: expensiveCalculation(item)
}));

// 排序
itemsWithKey.sort((a, b) => a.sortKey - b.sortKey);

// 提取结果
const sortedItems = itemsWithKey.map(entry => entry.original);

🌍 国际化排序

多语言支持

const words = ['äpple', 'apple', 'banana', 'Ångström'];

// 瑞典语排序
words.sort((a, b) => a.localeCompare(b, 'sv'));

// 德语排序
words.sort((a, b) => a.localeCompare(b, 'de'));

// 中文拼音排序
const chineseNames = ['张三', '李四', '王五'];
chineseNames.sort((a, b) => a.localeCompare(b, 'zh-CN'));

📝 实用工具函数

通用排序函数

function sortBy(array, key, order = 'asc') {
    return [...array].sort((a, b) => {
        const aVal = typeof key === 'function' ? key(a) : a[key];
        const bVal = typeof key === 'function' ? key(b) : b[key];

        let result = 0;
        if (aVal < bVal) result = -1;
        if (aVal > bVal) result = 1;

        return order === 'desc' ? -result : result;
    });
}

// 使用示例
const users = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}];
sortBy(users, 'age'); // 按年龄升序
sortBy(users, user => user.name.length, 'desc'); // 按名字长度降序

最佳实践总结

  1. 总是使用比较函数进行数值排序
  2. 保护原数组:先拷贝再排序
  3. 使用 localeCompare 进行字符串排序
  4. 考虑稳定性:需要时实现稳定排序
  5. 性能优化:对大数据集预计算排序键

🎯 一句话总结

.sort() 是原地排序方法,必须提供比较函数才能正确排序数值,建议先拷贝再排序以保护原数据!