Gernar
JavaScript: язык и типы

Как скопировать один объект в другой в JavaScript

Разбор вопроса «Как скопировать один объект в другой в JavaScript» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.

Вопрос

Как скопировать один объект в другой в JavaScript

Профессия

Frontend Developer

Что хочет услышать интервьюер

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

Ключевые тезисы

  • Поверхностное копирование через Object.assign() или spread-оператор {...obj} — копирует только верхний уровень, вложенные объекты остаются ссылками.
  • Глубокое копирование через JSON.parse(JSON.stringify(obj)) — работает для простых структур, но теряет функции, undefined и циклические ссылки.
  • Использование библиотек (например, lodash.cloneDeep) для надежного глубокого копирования сложных объектов.
  • Упомянуть structuredClone() (доступен в современных браузерах) как стандартный способ глубокого копирования, поддерживающий больше типов данных, чем JSON-метод.

Подробный ответ

В JavaScript копирование объектов может быть поверхностным или глубоким. Поверхностное копирование создает новый объект, но вложенные объекты остаются ссылками на оригинальные. Для этого используют Object.assign() или spread-оператор {...obj}. Глубокое копирование создает полностью независимую копию, включая все вложенные объекты. Самый простой способ — JSON.parse(JSON.stringify(obj)), но он имеет ограничения: не копирует функции, undefined, Symbol и циклические ссылки. Для сложных случаев лучше использовать structuredClone() (доступен в современных браузерах) или библиотеки вроде lodash.cloneDeep.

Практические примеры

Пример 1

Поверхностное копирование:

const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
shallowCopy.b.c = 3;
console.log(original.b.c); // 3 (изменился оригинал)

Пример 2

Глубокое копирование через JSON:

const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 3;
console.log(original.b.c); // 2 (оригинал не изменился)

Пример 3

Использование structuredClone():

const original = { a: 1, b: { c: 2 } };
const deepCopy = structuredClone(original);
deepCopy.b.c = 3;
console.log(original.b.c); // 2 (оригинал не изменился)

Частые ошибки

  • Использование поверхностного копирования, когда нужно глубокое, что приводит к неожиданным изменениям оригинала
  • Применение JSON.parse(JSON.stringify()) для объектов с функциями или циклическими ссылками, что приводит к потере данных

Связанные темы

  • Иммутабельность в JavaScript
  • Работа с ссылочными типами данных
  • Методы работы с объектами в JavaScript

Follow-up вопросы

В чем разница между поверхностным и глубоким копированием?

Уровень: basic

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

Какие ограничения есть у метода JSON.parse(JSON.stringify(obj))?

Уровень: intermediate

Этот метод не копирует функции, undefined, Symbol и циклические ссылки. Также он не поддерживает типы данных, такие как Map, Set и другие специфические объекты.

Когда стоит использовать библиотеки для глубокого копирования, такие как lodash.cloneDeep?

Уровень: intermediate

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

Какие преимущества у метода structuredClone() по сравнению с JSON.parse(JSON.stringify(obj))?

Уровень: advanced

structuredClone() поддерживает больше типов данных, таких как Map, Set, ArrayBuffer, и корректно обрабатывает циклические ссылки, что делает его более универсальным и надежным.

Как бы вы реализовали глубокое копирование вручную, если нельзя использовать сторонние библиотеки?

Уровень: advanced

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

Содержание