修复 JavaScript 中 .sort() 方法的问题:两个数组排序而不是只有一个
Array.prototype.sort() 函数的一个特性是它是一种就地排序算法,这意味着它不会创建要排序的数组的新副本,它在不使用任何额外空间的情况下对数组进行排序,使其更有效率和性能。但这种特性有时会导致尴尬的情况。
让我们用一个例子来理解这一点。假设,我们有一个 names 数组,其中包含一些字符串文字。我们希望保持此数组的顺序不变,并希望另一个数组包含与 names 数组相同的元素,但按字母顺序排序。
我们可以这样做:
const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj']; let sortedNames = names; sortedNames = sortedNames.sort(); console.log(names); console.log(sortedNames);
但众所周知,在 JavaScript 中,数组也是对象,对象是按引用复制而不是按值复制,因此对一个数组进行排序会导致两个数组都进行排序,这显然不是我们想要的。
解决方案
1. 在初始化新数组时使用 slice()
示例
const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj']; let sortedNames = names.slice(); sortedNames = sortedNames.sort(); console.log(names); console.log(sortedNames);
slice() 方法实际上返回一个浅拷贝,将其复制到一个新的数组中,如果未提供任何参数,则从开始复制到结束。
虽然此方法效率不高,因为它包括初始化一个新数组,并且仅对字符串/数字文字数组有效,但第二种方法效率更高,并且也适用于对象数组。
2. 使用 JSON.stringify() / JSON.parse()
示例
const names = ['Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj']; let sortedNames = JSON.parse(JSON.stringify(names)); sortedNames = sortedNames.sort(); console.log(names); console.log(sortedNames);
将数组转换为 JSON 字符串,然后转换回数组,这使得编译器不会按引用复制。
两种方法的输出在控制台中将相同:
输出
[ 'Rakesh', 'Mukesh', 'Ram', 'Anshul', 'Dheeraj' ] [ 'Anshul', 'Dheeraj', 'Mukesh', 'Rakesh', 'Ram' ]
广告