2014-01-20 2 views
2

скажем у меня есть массив, var animals = ["dog","cat","rat"];Javascript Передавать по ссылке обходного

тогда я определяю var pets = animals;

тогда я называю pets.shift();

теперь, потому что браузер пройти по ссылке для массивов, если я сейчас позвоню animals, я получаю ["cat","rat"].

Мой вопрос: есть ли способ обойти это, если я позже хотел бы использовать animals в его неизмененной форме?

ответ

7

Примечание по терминологии: JavaScript является never (независимо от того, сколько раз вы слышите, что люди говорят, что это так). Когда вы пишете строку:

var pets = animals; 

Вы присваивая значение из animals в pets. Значение, которое назначено, является ссылкой на массив, так что теперь обе переменные ссылаются на на тот же объект в памяти. (Примечание: это немного педантично, но у него также есть свойство быть правильно.)

Если вы хотите, чтобы эти две переменные ссылались на два разных массива, вам необходимо создать копию оригинала массив и назначить ссылку на это значение pets. Наиболее распространенный способ сделать это в JavaScript, чтобы воспользоваться тем фактом, что некоторые методы массива (как slice или concat) создать копию массива, на котором они называются:

var pets = animals.concat(); 

Доказательство в/равенство:

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 и следует рассматривать е или очень большие массивы. (В большинстве случаев просто сделайте то, что наиболее читаемо.)

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

+0

спасибо за подробный ответ. тонкое различие, которое я буду тратить некоторое время, обворачивая мой мозг. –

+0

так что - если скопированный массив содержит и объект, который затем изменен, я мог бы иметь такую ​​же проблему. –

+0

Да.Вы можете посмотреть здесь: http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object –

3

Вы должны клонировать массив, который делается с

var savedAnimals = animals.slice(); 

Обратите внимание, что это не глубокий клон: он не защищает элементы внутри от модификации (если они не строки) ,

+0

yup, это работает. благодаря! любые другие стратегии? –

+0

это лучшее, что у вас есть, и это стандартное. –

Смежные вопросы