JavaScript: Jak stworzyć głęboką kopię zagnieżdżonego obiektu?
Opublikowano: 18.08.2022 - tagi: JavaScript Obiekt Kopia
Kopiowanie obiektu
Stworzenie kopii obiekt jest proste:
const originalObj = {
title: 'Foo',
value: 100,
tags: ['a', 'b', 'c']
};
const copyObj = {
...originalObj
};
copyObj.title = 'Bar';
copyObj.value = 50;
copyObj.tags.push('d');
console.log('originalObj: ', originalObj); // { title: 'Foo', value: 100, tags: ['a', 'b', 'c'] }
console.log('copyObj: ', copyObj); // { title: 'Bar', value: 50, tags: ['a', 'b', 'c', 'd'] }
Za pomocą operatora spread: ... tworzymy kopię obiektu. Następnie zmieniamy w skopiowanym obiekcie jego parametry. Oryginał się nie zmieniał. I tak miało być :)
Niestety to nie zadziała dla obiektu zagnieżdżonego.
Kopiowanie obiektu zagnieżdżonego
Najpierw przykład:
const originalObj = {
name: 'Janusz Kowalski',
age: 57,
address: {
city: 'New York',
street: '99 East Golf Street'
}
};
const copyObj = {
...originalObj
};
copyObj.name = 'Grażyna Kowalska';
copyObj.address.city = 'Chicago';
copyObj.address.street = '3109 15th St';
console.log('originalObj: ', originalObj);
/*
originalObj:
{
name: 'Janusz Kowalski',
age: 57,
address: {
city: 'Chicago',
street: '3109 15th St'
}
}
*/
console.log('copyObj: ', copyObj);
/*
copyObj:
{
name: 'Grażyna Kowalska',
age: 57,
address: {
city: 'Chicago',
street: '3109 15th St'
}
}
*/
Kopia została stworzona, ale nie dla zagnieżdżonej części obiektu jak: address. Po zmianie danych w kopii zmieniły się też dane w oryginale!
Jak sobie z tym poradzić?
const originalObj = {
name: 'Janusz Kowalski',
age: 57,
address: {
city: 'New York',
street: '99 East Golf Street'
}
};
const copyObj = JSON.parse(JSON.stringify(originalObj))
copyObj.name = 'Grażyna Kowalska';
copyObj.address.city = 'Chicago';
copyObj.address.street = '3109 15th St';
console.log('originalObj: ', originalObj);
/*
originalObj:
{
...,
address: {
city: 'New York',
street: '99 East Golf Street'
}
}
*/
console.log('copyObj: ', copyObj);
/*
copyObj:
{
...,
"address": {
"city": "Chicago",
"street": "3109 15th St"
}
}
*/
Kombinacja: JSON.parse i JSON.stringify rozwiązuje ten problem.
To rozwiązanie nie zadziała jeśli obiekt zawiera funkcje. Funkcje nie zostaną skopiowane.