Как скопировать один объект в другой в 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
Можно реализовать рекурсивную функцию, которая будет обходить объект и копировать все его свойства, включая вложенные объекты и массивы, с учетом различных типов данных.
Как изолировать var в функциональной области видимости
Разбор вопроса «Как изолировать var в функциональной области видимости» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.
В какой области видимости работает var
Разбор вопроса «В какой области видимости работает var» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.