Дмитрий Нечаев
Поверхностное и глубокое копирование в JavaScript
При работе с объектами и массивами в JavaScript часто возникает необходимость копировать их для изменения или передачи в функции без изменения оригинала. Однако копирование объектов и массивов может быть поверхностным или глубоким, и понимание разницы между этими подходами важно для правильной работы с данными.
Поверхностное копирование
При поверхностном копировании создается новый объект или массив, и его свойства или элементы копируются из оригинала. Однако если свойства объекта или элементы массива сами являются объектами или массивами, они копируются по ссылке, а не по значению.
Пример поверхностного копирования
const original = {
name: 'John',
age: 30,
hobbies: ['reading', 'swimming']
};
const shallowCopy = Object.assign({}, original);
shallowCopy.hobbies.push('cooking');
console.log(original); // { name: 'John', age: 30, hobbies: ['reading', 'swimming', 'cooking'] }
console.log(shallowCopy); // { name: 'John', age: 30, hobbies: ['reading', 'swimming', 'cooking'] }
В этом примере мы создали поверхностную копию объекта original
с помощью Object.assign()
. После добавления нового хобби в копию, изменение также отобразилось в оригинале, потому что свойство hobbies
копировалось по ссылке.
Глубокое копирование
Глубокое копирование создает полностью независимую копию объекта или массива, включая все вложенные объекты и массивы. Таким образом, изменения в копии не влияют на оригинал и наоборот.
Пример глубокого копирования
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj; // если не объект или null, вернуть сам объект
}
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
copy[key] = deepCopy(obj[key]); // рекурсивно копируем свойства объекта
}
return copy;
}
const original = {
name: 'John',
age: 30,
hobbies: ['reading', 'swimming']
};
const deepClone = deepCopy(original);
deepClone.hobbies.push('cooking');
console.log(original); // { name: 'John', age: 30, hobbies: ['reading', 'swimming'] }
console.log(deepClone); // { name: 'John', age: 30, hobbies: ['reading', 'swimming', 'cooking'] }
В этом примере мы определили функцию deepCopy()
, которая рекурсивно копирует все свойства объекта. Как результат, изменения в deepClone
не влияют на original
.
Заключение
Понимание разницы между поверхностным и глубоким копированием важно при работе с объектами и массивами в JavaScript. Поверхностное копирование подходит для простых случаев, но при наличии вложенных структур необходимо использовать глубокое копирование, чтобы избежать неожиданных побочных эффектов.