2015-10-02 1 views
3

Ниже приведен мой код для изменения объекта внутри массива в строку. Не могу понять, почему он влияет на исходный массив. slice предполагается клонировать массив, если я прав?Почему список клонирования с использованием эффектов среза в исходном списке

var cloned = $scope.selected.items.slice(0); 
cloned.forEach(function (cluster) { 
    cluster.status = cluster.status.name; 
}) 
ObjToPost.MO = cloned; 
console.log("consoling the cluster list", ObjToPost.MO); 
console.log("consoling the original cluster list", $scope.selected.items); 

После того, как утешительное массивы являются одинаковыми

+1

Я не вижу вас клонировать что-нибудь! Клонированный - это прямая ссылка для исходного списка. – Fals

ответ

7

Цитирование MDN на Array.prototype.slice,

Метод slice() возвращает неполную копию части массива в новый объект массива.

Важными словами здесь являются «мелкая копия». Он создает новый массив и заставляет элементы массива указывать на один и тот же объект.

В вашем случае даже после нарезки каждый элемент массива как в исходном, так и в клонированном массивах ссылается на те же объекты кластера в памяти.

Original      Cloned 
+-----+      +-----+ 
| 0 |--> Cluster Object 1 <--| 0 | 
+-----+      +-----+ 
| 1 |--> Cluster Object 2 <--| 1 | 
+-----+      +-----+ 
| 2 |--> Cluster Object 3 <--| 2 | 
+-----+      +-----+ 

Поскольку все соответствующие элементы имеют в виду те же объекты, изменяя его через один массив будет отражено в другом, а также.

Примечание: Если вы ищете способ сделать глубокую копию, то вы можете проверить this question.

+0

Есть ли способ скопировать массив – Tushar

+0

Я хочу, чтобы исходный массив оставался незатронутым, и я должен получить временную копию того же массива, который, кстати, мне нужен POST после его модификации –

+0

Я пробовал использовать $. расширяется, но, похоже, он может клонировать только объекты, а не массивы, тогда как массивы также являются объектами. –

0

Как объясняет @thefourtheye, вы создаете мелкую копию массива. Для глубокой копии элементы массива, а также изменить статус, вы можете использовать Array.prototype.map с angular.merge():

ObjToPost.MO = $scope.selected.items.map(function(cluster) { 
    return angular.merge({}, cluster, { status: cluster.status.name }); // create a deep copy of each item, and override status with status.name 
}); 
Смежные вопросы