2016-06-10 2 views
4

Предполагается, что Array.slice() позволяет мне сделать копию массива, а затем я могу изменить эту копию без изменения исходного массива, но когда я используйте Array.forEach() над копией для удаления некоторых значений. Эти значения также удаляются из исходного массива. У кого-нибудь есть идея, почему это происходит? Вот код, который я использовал:Array.forEach() и Array.slice() вместе работают неправильно

var originalArray = [ 
    { id: 1, name: 'Sales', datasources: [ 
     { id:1 , name: 'datasource1', fields: [] }, 
     { id:2 , name: 'datasource2', fields: [] }, 
    ] }, 
    { id: 4, name: 'Accounts', datasources: [ 
     { id:3 , name: 'datasource3', fields: [] }, 
     { id:4 , name: 'datasource4', fields: [] }, 
    ] }, 
    { id: 123, name: 'my datasources', datasources: [ 
     { id:1 , name: 'datasource1', fields: [] }, 
     { id:2 , name: 'datasource2', fields: [] }, 
     { id:3 , name: 'datasource3', fields: [] }, 
     { id:4 , name: 'datasource4', fields: [] }, 
    ] }, 
    { id: 12, name: 'shared datasources', datasources: [ 
     { id:13 , name: 'myshared datasource', fields: [] }, 
     { id:16 , name: 'hello test', fields: [] }, 
    ] }, 
]; 

var copyOfOriginalArray = originalArray.slice(); 

copyOfOriginalArray.forEach((folder, index) => { 
    folder.datasources = folder.datasources.filter((o) => { return o.name.trim().toLowerCase().includes('hello'); }); 
}); 

JSON.stringify(originalArray); 
JSON.stringify(copyOfOriginalArray); 
+0

«Для ссылок на объекты (а не сам объект), ломтик копирует ссылки на объекты в новый массив И оригинал и новый массив обратитесь к одному и тому же объекту. Если объект, на который ссылается, изменяется, изменения видны как для нового, так и для оригинального массива ». из документации MDN для Array.prototype.slice() –

ответ

5

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

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

для глубокого копирования любого объекта в JavaScript вы можете использовать эту функцию:.

function deepCopy(oldObj) { 
    var newObj = oldObj; 
    if (oldObj && typeof oldObj === 'object') { 
     newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {}; 
     for (var i in oldObj) { 
      newObj[i] = deepCopy(oldObj[i]); 
     } 
    } 
    return newObj; 
} 
+1

спасибо большое, я был смущен этим с некоторыми функциями, но это полезно –

4

фрагмент создаст копию самого массива, но это не будет клонировать объекты в массиве (те все еще будут ссылки).

Вам нужно будет рекурсивно клонировать массив и его содержимое или использовать что-то вроде Lodash-х cloneDeep

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