> Почему нельзя использовать JSON.stringify и JSON.parse для глубокого копирования объектов с функциями в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: EdenAI
Стек: JavaScript
> Пример ответа
Короткий ответ
JSON.stringify и JSON.parse не работают с функциями, так как JSON - это формат для представления только данных (строк, чисел, массивов, объектов, null). Функции не являются частью спецификации JSON, поэтому при сериализации они просто отбрасываются. В результате при десериализации получается объект без методов, что делает глубокое копирование неполным.
Подробное объяснение
JSON.stringify преобразует объект в строку JSON, но игнорирует все значения, которые не поддерживаются форматом: функции, undefined, Symbol, а также специальные объекты вроде Map, Set, Date (Date превращается в строку, но не восстанавливается корректно). При вызове JSON.parse эта строка превращается обратно в объект, но функции уже потеряны безвозвратно.
Кроме того, JSON.stringify не обрабатывает циклические ссылки - если объект ссылается сам на себя, будет выброшена ошибка. Также теряются прототипы объекта, свойства-геттеры и сеттеры, а значения undefined в массивах заменяются на null.
Для глубокого копирования объектов с функциями нужно использовать рекурсивное копирование с проверкой типа каждого свойства, либо библиотеки вроде lodash.cloneDeep, которая умеет обрабатывать функции (но не гарантирует корректное копирование замыканий).
На практике
В реальных проектах JSON.parse(JSON.stringify(obj)) часто используют для быстрого копирования простых data-объектов без функций - например, конфигов, ответов API, состояния UI. Но если объект содержит методы, классы с прототипами, Map, Set, Date или циклические ссылки, этот подход неприменим.
Для копирования объектов с функциями обычно пишут собственную утилиту или используют structuredClone (но он тоже не копирует функции). Альтернатива - ручное копирование с помощью spread-оператора или Object.assign для поверхностного копирования, либо рекурсивная функция с проверкой typeof.
Пример кода
JAVASCRIPTconst obj = {name: 'test',greet: function() { console.log('hello'); },nested: { value: 42 }};const copy = JSON.parse(JSON.stringify(obj));console.log(copy.greet); // undefined - функция потерянаconsole.log(copy.nested.value); // 42 - данные скопированы// Рекурсивное копирование с функциямиfunction deepClone(obj) {if (obj === null || typeof obj !== 'object') return obj;if (typeof obj === 'function') return obj; // копируем ссылкуconst clone = Array.isArray(obj) ? [] : {};for (let key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key]);}}return clone;}
Как отвечать на собеседовании
Начни с краткого объяснения, что JSON не поддерживает функции. Затем перечисли основные ограничения: потеря функций, undefined, Symbol, циклические ссылки, прототипы. Приведи пример, когда это критично - например, копирование объекта с методами. Упомяни альтернативы: рекурсивное копирование, structuredClone (с оговорками), библиотеки. Покажи понимание, что функции копируются по ссылке, а не создаются заново - это важно для замыканий.
Что проверяет интервьюер
Интервьюер оценивает понимание спецификации JSON, осведомлённость о граничных случаях (циклические ссылки, специальные типы), умение выбирать подходящий инструмент для задачи. Также проверяется знание внутреннего устройства объектов JavaScript: различие между данными и методами, работа прототипов, поведение typeof. Для senior-уровня важно показать не только знание проблемы, но и понимание trade-off при выборе альтернатив.
Типичные ошибки
Кандидаты часто утверждают, что JSON.stringify "ломает" функции, хотя на самом деле он их игнорирует - разница важна для понимания. Другая ошибка - считать, что structuredClone решает проблему с функциями (он тоже их не копирует). Также путают поверхностное и глубокое копирование: JSON.parse(JSON.stringify(obj)) - глубокое, но неполное. Некоторые забывают про циклические ссылки, которые вызывают ошибку, а не тихую потерю данных.
> Похожие задачи по frontend
Что такое ECMAScript
Какие есть стандарты JavaScript
Что происходит при запуске бесконечной рекурсивной функции с console.log в браузере
Что такое иммутабельность в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью