Любимая Вебня пишет, что в браузерах скоро появится функция window.structuredClone(), но не поясняет, почему это классно.



TL;DR: structuredClone — это как _.cloneDeep(), но из коробки и быстрее.



Структурное клонирование

Сейчас есть плюс-минус два способа склонировать объект:

_.cloneDeep(obj) и

JSON.parse(JSON.stringify(obj))



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



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



const a = { b: { c: 5 } }

history.pushState(a, document.title)

a.b.c = 6




то в истории всё равно останется объект { b: { c: 5 } }. Браузер склонирует объект a перед тем, как сохранить его в историю. Это называется «структурное клонирование» («structured clone»).



Хаки

Получается, сейчас структурное клонирование доступно в разных браузерных API типа history.pushState или postMessage, но нигде не выставлено наружу. В итоге, если вам надо склонировать объект, но вы не можете подключить lodash, приходится писать что-то такое:



const oldState = history.state;

history.replaceState(obj, document.title);

const copy = history.state;

history.replaceState(oldState, document.title);

return copy;




(Плиз, не делайте так.)



Что теперь

Теперь в спеке есть функция structuredClone(). Она делает то же, что и _.cloneDeep(), но без подключения внешних библиотек и (как минимум в Deno) быстрее.



В браузерах прогресс реализации можно отслеживать по implementation-багам. А в Deno self.structuredClone() реализовали уже вчера