Выбор ответа Senior Реализация с нуля обновлено
deepClone падает на циклической ссылке
Вопрос
Функция падает на объекте o, где o.self = o. Какое исправление верное?
function deepClone(value, seen = new WeakMap()) {
if (value === null || typeof value !== 'object') return value;
if (seen.has(value)) return seen.get(value);
const copy = Array.isArray(value) ? [] : {};
for (const key of Object.keys(value)) {
copy[key] = deepClone(value[key], seen);
}
seen.set(value, copy);
return copy;
}
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Перенести seen.set(value, copy) до цикла по ключам. Копия регистрируется в seen только после обхода всех ключей.
Варианты ответа
- Перенести
seen.set(value, copy)до цикла по ключамправильный ответ - Заменить
WeakMapнаMap, чтобы ссылка наoне терялась - Заменить
Object.keysнаfor...in, чтобы обход шёл лениво - Проверять
seen.has(value)после цикла по ключам, а не до него
Разбор
Копия регистрируется в seen только после обхода всех ключей. Когда рекурсия доходит до o.self, в seen ещё пусто, и функция снова начинает копировать o, уходя в бесконечную рекурсию до RangeError. Если записать пару в seen сразу после создания copy, повторная встреча вернёт уже создаваемую копию, и цикл замкнётся правильно. Тип словаря и способ перебора ключей на проблему не влияют, а проверка после цикла бессмысленна.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.