如何在排序前保存数组的副本



我正在尝试在排序之前保存数组的副本:

words_Array = ["Why", "doesnt", "this", "work?"];
var sortedWords_Array = words_Array;
sortedWords_Array.sort(function(a, b){
    return b.length - a.length;
});
alert("sortedWords_Array is :"+sortedWords_Array);
alert("words_Array is :"+words_Array);

在我排序sortedWords_Array之后,由于某种原因,它们都被排序了。 http://jsfiddle.net/zv39J/这是为什么呢?

因为在javascript中,数组是通过引用传递的,这意味着当你使一个数组等于另一个数组时,只要你对一个数组进行编辑,它就会改变。 若要在示例中解决此问题,请更改以下行:

var sortedWords_Array = words_Array;

自:

 //make a copy of array by using slice
 var sortedWords_Array = words_Array.slice(0);

有关其他用途和更深入的解释,请参阅此处:

slice 不会更改原始数组,但返回一个新的"一级" 深层"副本,其中包含从 原始阵列。

Array.prototype.slice()

对要复制的数组执行slice(),然后排序。

var sortedWords_Array = words_Array.slice();

使用 slice 函数制作快速复制。

http://jsfiddle.net/zv39J/2/

另一方面,警报很糟糕。没有人愿意点击一个jsfiddle,只是为了迎接一系列警报窗口。我已经更新了小提琴以包含jQuery,它允许我们使用简洁的语法来更新HTML。

这不起作用,因为当您尝试分配时 var sortedWords_Array = words_Array;

words_array的引用将传递给sortedWords_Array。因此,对sortedWords_Array所做的任何更改都将反映在words_array上。

由于 Array.slice() 不进行深度复制,因此它不适合多维数组:

var a =[[1], [2], [3]];
var b = a.slice();
b.shift().shift();
// a is now [[], [2], [3]]

请注意,尽管我在上面使用了 shift().shift(),但重点只是b[0][0]包含指向a[0][0]的指针而不是值。

同样,delete(b[0][0])也会导致删除a[0][0]b[0][0]=99也会更改a[0][0] to 99.

当将 true 值作为初始参数传递时,jQuery's extend该方法会执行深层复制:

var a =[[1], [2], [3]];
var b = $.extend(true, [], a);
b.shift().shift();
// a is still [[1], [2], [3]]

最新更新