логотип PurpleSchool
логотип PurpleSchool

Поверхностное и глубокое копирование в 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. Поверхностное копирование подходит для простых случаев, но при наличии вложенных структур необходимо использовать глубокое копирование, чтобы избежать неожиданных побочных эффектов.

Стрелочка влевоSpread в JavaScriptИтераторы в JavaScriptСтрелочка вправо

Все гайды по Javascript

Как работает метод trim() - JavaScriptКак работает метод toUpperCase() - JavaScriptКак работает метод toLowerCase() - JavaScriptКак работает метод substring() - JavaScriptКак работает метод startsWith() - JavaScriptКак работает метод split() - JavaScriptКак работает метод slice() - JavaScriptКак работает метод search() - JavaScriptКак работает метод replaceAll() - JavaScriptКак работает метод replace() - JavaScriptКак работает метод repeat() - JavaScriptКак работает метод padStart() - JavaScriptКак работает метод padEnd() - JavaScriptКак работает метод matchAll() - JavaScriptКак работает метод match() - JavaScriptКак работает метод localeCompare() - JavaScriptКак работает свойство length - JavaScriptКак работает метод lastIndexOf() - JavaScriptКак работает метод indexOf() - JavaScriptКак работает метод includes() - JavaScriptКак работает метод fromCodePoint() - JavaScriptКак работает метод fromCharCode() - JavaScriptКак работает метод endsWith() - JavaScriptКак работает метод concat() - JavaScriptКак работает метод codePointAt() - JavaScriptКак работает метод charCodeAt() - JavaScriptКак работает метод charAt() - JavaScript
Итератор в JavaScript
try...catch в JavaScriptError в JavaScript
Событие wheel в JavaScriptСобытие unload в JavaScriptСобытие touch в JavaScriptСобытие submit в JavaScriptСобытие scroll в JavaScriptСобытие reset в JavaScriptМетод .preventDefault() в JavaScriptСобытие mouseover в JavaScriptСобытие mouseout в JavaScriptСобытие load в JavaScriptСобытие keyup в JavaScriptСобытие keydown в JavaScriptСобытие invalid в JavaScriptСобытие input в JavaScriptСобытийная модель Event в JavaScriptОбъект события Event в JavaScriptСобытие DOMContentLoaded в JavaScriptСобытие dblclick в JavaScriptСобытие click в JavaScriptСобытие change в JavaScriptСобытие beforeunload в JavaScript
Как работает метод some() - JavaScriptКак работает метод reverse() - JavaScriptКак работает метод reduce() - JavaScriptКак работает метод map() - JavaScriptКак работает метод isArray() - JavaScriptКак работает метод indexOf() - JavaScriptКак работает метод includes() - JavaScriptКак работает метод from() - JavaScriptКак работает метод forEach() - JavaScriptКак работает метод flatMap() - JavaScriptКак работает метод flat() - JavaScriptКак работает метод findIndex() - JavaScriptКак работает метод find() - JavaScriptКак работает метод filter() - JavaScriptКак работает метод every() - JavaScriptМассивы в JavaScript
Открыть базу знаний