JS имеет только пройти по значению. Просто хотел прояснить это с самого начала.
Чтобы все было в порядке, приведенный ниже код иллюстрирует разницу между переходящим значением и пропуском-ref.
проход по значению
function change (x) { x = 7; }
var x = 1;
change(x);
console.log(x); // 1
передачи по исм (не доступны в JS)
function change (x) { x = 7; }
var x = 1;
change(x);
console.log(x); // 7
Теперь, вы должны понимать, что некоторые типы выделяются на куча, в то время как другие выделены в стеке. Так что это значит?
Ну, давайте предположим, что у вас есть переменная.
var x = 5;
Здесь значение живет на стеке. Что означает, если я
var y = x;
у меня будет две переменные в стеке, как со своей собственной копией 5
.
Простые типы всегда выделяются в стеке.
Объекты, с другой стороны, живые в куче.Когда я,
var o1 = {x: 5};
объект будет выделен в куче, но значение в пределах o1
переменных, которая является ссылкой на объект в куче (назовет #ref1
значения в пределах o1
переменных), будет выделенных в стеке. Что означает, если я
var o2 = o1;
у меня будет две переменные в стеке, как со своей собственной копией #ref1
, но только один объект, выделенный в куче.
Теперь вы можете использовать ссылку для доступа к членам объекта, и потому как o1
и o2
содержат ссылку на тот же объект, они смогут найти объект в куче в изменение его x
значения. Если, однако, я следующий
o2 = {x: 7};
это изменит значение, сохраненное в стеке для переменной o2
(будем называть новое значение #ref2
). Теперь в куче есть два объекта и две ссылки, хранящиеся в стеке.
Наконец, давайте поговорим о вашей проблеме:
// the array (which is an object) is allocated on the heap
// {animals} variable will contain a reference to that object (#ref1)
var animals = ["dog", "cat"];
// pass-by-value
pushSearchList(animals);
// local variable {passedAnimals} will contain a copy of #ref1
// but both {passedAnimals} and {animals} can modify the same object
function pushSearchList(passedAnimals){
var localAnimals = passedAnimals;
localAnimals.shift();
alert(animals);
}
Теперь, если вы хотите иметь свой собственный экземпляр объекта массива? Просто клонируйте массив, используя:
// {arr} will receive reference to a new array allocated on the heap (#ref2)
var arr = passedAnimals.slice(0);
Массивы и объекты являются исключениями. Они используют одну и ту же ссылку. Вы должны узнать об этом :) –
Это не делает копию. Это назначение, как и любая другая переменная. См. Http://stackoverflow.com/a/5314911/707111. Вы можете копировать массивы с помощью '.slice()'. – Ryan
Dupe - http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – adeneo