2015-02-12 17 views
16

Копирование массива объектов в другой массив в javascript с помощью среза (0) и concat() не работает.Копирование массива объектов в другой массив в javascript (Deep Copy)

Я попробовал следующее проверить, если я получу ожидаемое поведение глубокой копии, используя это. Но исходный массив также изменяется после внесения изменений в скопированный массив.

var tags = []; 
for(var i=0; i<3; i++) { 
    tags.push({ 
     sortOrder: i, 
     type: 'miss' 
    }) 
} 
for(var tag in tags) { 
    if(tags[tag].sortOrder == 1) { 
     tags[tag].type = 'done' 
    } 
} 
console.dir(tags) 

var copy = tags.slice(0) 
console.dir(copy) 

copy[0].type = 'test' 
console.dir(tags) 

var another = tags.concat() 
another[0].type = 'miss' 
console.dir(tags) 

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

+0

Я не уверен, что вы пытаетесь сделать, но. Я предлагаю изменить второй цикл for на 'for of' loop' for (var tag тегов) {if (tag.sortOrder == 1) { tag.type == 'done' }} ' –

+0

В зависимости от вашей среды вы можете попробовать Object.create? – Zlatko

+0

@zlatko вы можете привести пример того же – jsbisht

ответ

63

Попробуйте

var copy = JSON.parse(JSON.stringify(tags)); 
+1

Я использую то же самое сейчас. Это прекрасно работает. – jsbisht

+0

Более полутора лет, и все еще полезно! –

+0

Я понятия не имею, почему это работает – Aerious

14

Попробуйте следующее

// Deep copy 
var newArray = jQuery.extend(true, [], oldArray); 

Для получения более подробной информации проверить этот вопрос из What is the most efficient way to deep clone an object in JavaScript?

+0

Это не работает, потому что результатом является объект, а не массив. –

4

Как уже упоминалось Here.slice(0) будет эффективно клонировать массив примитивного типа элементы. Однако в вашем примере массив tags содержит анонимные объекты. Следовательно, любые изменения этих объектов в клонированном массиве отражаются в массиве tags.

@ ответ dangh над derefences эти объекты элемента и создать новые.

Here is another thread решения аналогичной ситуации

-1

Для этого я использовать новый ECMAScript 6 Object.assign метод:

let oldObject = [1,3,5,"test"]; 
let newObject = Object.assign({}, oldObject) 

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

также Вы можете добавить другие объекты для копирования:

let newObject = Object.assign({}, oldObject, o2, o3, ...) 
+0

даже с Object.assign у вас есть те же проблемы, каждый метод, который существует прямо сейчас, в Javascript работает нормально с примитивами, если у вас есть свой объект с ключами, которые имеют значение другого объекта, ссылки будут сохранены – darkyndy

0

Самый простой и оптимистичный способ сделать это в одной строке с помощью Underscore/Lodash

let a = _.map(b, _.clone)

0

Тот же вопрос случиться со мной. У меня есть данные из службы и сохраняются в другой переменной. Когда я обновляю свой массив, скопированный массив также обновляется. старый код, как показано ниже

//$scope.MyData get from service 
 
$scope.MyDataOriginal = $scope.MyData;

Так что, когда я когда-либо изменить $ scope.MyData также изменить $ scope.MyDataOriginal. я нашел решение, которое angular.copy правильный код, как показано ниже

$scope.MyDataOriginal = angular.copy($scope.MyData);

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