> Почему нельзя использовать 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.

Пример кода

JAVASCRIPT
const 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)) - глубокое, но неполное. Некоторые забывают про циклические ссылки, которые вызывают ошибку, а не тихую потерю данных.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью