JavaScript .push () внутри функции переопределяет глобальную переменную - PullRequest
4 голосов
/ 30 августа 2010

У меня следующая проблема с методом .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 ]

9 голосов
/ 30 августа 2010

Массивы в Javascript (и большинстве других языков) передаются по ссылке.

Когда вы пишете add(myArray), вы передаете ссылку на тот же экземпляр массива, на который ссылается глобальная переменная myArray.
Любые изменения в объекте массива будут видны через обе ссылки.

Чтобы скопировать фактический экземпляр массива, напишите add(myArray.slice());.
Обратите внимание, что это не будет копировать объекты внутри него.

4 голосов
/ 30 августа 2010

Если вам нужно иметь возможность вкладывать массивы, я бы изменил функцию .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().

Это также дает вам преимущество передачи другого массива вместо строки, поэтому:

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

даст вам:

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

вместо:

// ["a", "b", "c", "d", ["e", "f"] ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...