函数内的JavaScript .push()覆盖了全局变量

时间:2010-08-29 22:16:08

标签: javascript arrays global-variables

.push()方法存在以下问题:

var myArray = ["a", "b", "c", "d"];

function add(arr) {
    arr.push("e");
    return arr;
}

add(myArray);

// myArray is now  ["a", "b", "c", "d", "e"]

为什么它会覆盖myArray?无法理解......

2 个答案:

答案 0 :(得分:9)

Javascript(和大多数其他语言)中的数组通过引用传递。

当您编写add(myArray)时,您将传递对全局myArray变量引用的同一Array实例的引用。
通过两个引用都可以看到对数组对象的任何更改。

要复制实际的数组实例,请写add(myArray.slice()); 请注意,这不会复制其中的对象。

答案 1 :(得分:4)

如果你需要能够嵌套数组,那么我将更改.add()函数,让.concat()将数组复制到一个变量中,.push()将新值复制到新的数组,并返回它。

function add(arr) {
    var newArr = arr.concat(); // duplicate
    newArr.push("e");      // push new value
    return newArr;         // return new (modified) Array
}

您也可以使用concat(),并返回它创建的新数组。

var myArray = ["a", "b", "c", "d"];

function add(arr) {
    return arr.concat("e");
}
var newArray = add(myArray);

console.log( newArray );  // ["a", "b", "c", "d", "e"]
console.log( myArray );   // ["a", "b", "c", "d"]

因此,您可以使用一个.slice()来完成它,而不是两个方法.push(),而不是.concat()

这也为您提供了传递另一个Array而不是字符串的好处,所以:

return arr.concat(["e","f"]);

会给你:

// ["a", "b", "c", "d", "e", "f"]

而不是:

// ["a", "b", "c", "d", ["e", "f"] ]