假设我有一个数组var animals = ["dog","cat","rat"];
然后我定义var pets = animals;
然后我致电pets.shift();
现在因为javascript是数组传递引用,如果我现在调用animals
,我会得到["cat","rat"]
。
我的问题:如果我以后想以未经修改的形式使用animals
,有什么方法吗?
答案 0 :(得分:7)
关于术语的说明:JavaScript 永远不会 pass-by-reference(无论你听到有多少人说它是这样)。当你写下这一行时:
var pets = animals;
您要将animals
的值分配给pets
。分配的值是对数组的引用,因此现在两个变量都将引用到内存中的同一对象。 (注意:这有点迂腐,但它也具有正确的好处。)
如果您希望这两个变量引用两个不同的数组,则需要创建原始数组的副本并将其引用分配给pets
。在JavaScript中执行此操作的最常见方法是利用某些数组方法(如slice
或concat
)创建它们被调用的数组副本的事实:
var pets = animals.concat();
in / equality的证明:
var arr = [];
arr1 = arr;
console.log(arr1 === arr); // true
console.log(arr1 === arr.concat()) // false
当然,您也可以自己执行复制:
function copy(arr) {
var i, len = arr.length, arr1 = new Array(len);
for (i = 0; i < len; i += 1) {
arr1[i] = arr[i];
}
return arr1;
}
确实,this is probably a lot faster并且应该考虑非常大的数组。 (在大多数情况下,只做最可读的事情。)
请注意,这些方法中的每一个都会创建原始数组的浅副本。如果数组保存对其他对象的引用,则将这些引用复制到新数组(即原始数组和新数组都将引用相同的对象)。另一方面,字符串和数字将直接复制到新数组中。
答案 1 :(得分:3)
你必须克隆数组,这是用
完成的var savedAnimals = animals.slice();
请注意,这不是深层克隆:它不会保护内部元素免受修改(如果它们不是字符串)。