13 декабря 2022 2048
Долгое время для создания глубоких копий значений в JavaScript разработчикам приходилось использовать обходные решения и библиотеки. Сейчас в JavaScript появилась встроенная функция structuredClone() для глубокого копирования, которая в разы облегчила жизнь джавистов. Этот API был реализован во всех браузерах, например, в Firefox версии Firefox 94. Еще одно преимущество API — он работает в Node 17 и Deno 1.14. Сегодня мы расскажем, как прямо сейчас начать использовать эту функцию, не испытывая никаких неудобств.
Глубокое копирование в JavaScript с использованием структурных клонов

Поверхностное копирование

Копирование значения в JavaScript почти всегда поверхностное, а не глубокое. Другими словами, изменения глубоко вложенных значений будут видимы как в копии, так и в оригинале.

Одним из способов создания поверхностной копии в JavaScript является использование оператора расширения объекта...:

const myOriginal = {
someProp: "with a string value",
anotherProp: {
    withAnotherProp: 1,
    andAnotherProp: true
}
};
const myShallowCopy = {...myOriginal};

Добавление или изменение свойства непосредственно в поверхностной копии повлияет только на копию, но не на оригинал:


myShallowCopy.aNewProp = "a new value";
console.log(myOriginal.aNewProp)
// ^ logs `undefined`

Однако добавление или изменение глубоко встроенных свойств влияет как на копию, так и на оригинал:


myShallowCopy.anotherProp.aNewProp = "a new value";
console.log(myOriginal.anotherProp.aNewProp)
// ^ logs `a new value`

Выражение {...myOriginal} проводит итерацию по (перечислимым) свойствам myOriginal с помощью оператора Spread. При этом используется имя и значение свойства, которое присваивается одно за другим заново создаваемому, пустому объекту. В результате мы получаем объект, который будет идентичен по форме, но со своей собственной копией списка свойств и значений. Значения также копируются, но так называемые примитивные значения обрабатываются JavaScript не так, как непримитивные значения. Процитируем MDN:

В JavaScript примитив (примитивное значение, примитивный тип данных) — это данные, которые не являются объектом и не имеют методов. Существует семь примитивных типов данных: string, number, bigint, boolean, undefined, symbol и null.

MDN — Примитив

Непримитивные значения обрабатываются как ссылки, т.е. копирование значения на самом деле это просто копирование ссылки на один и тот же базовый объект, что и приводит к поверхностному копированию.

11235921_11104.jpg

Глубокое копирование

Противоположность поверхностного копирования — глубокое копирование. Алгоритм его работы предполагает копирование свойств объекта одного за другим, но действует он рекурсивно, когда обнаруживает ссылку на другой объект, создавая также и копию этого объекта. Это чрезвычайно важно для того, чтобы два куска кода случайно не обращались к одному и тому же объекту и не управляли состоянием друг друга.

Раньше в JavaScript не было простого и удобного способа создания глубоких копий значения. Многие программисты полагались на сторонние библиотеки, например использовали функцию cloneDeep() библиотеки Lodash. Пожалуй, самым популярным решением этой проблемы было использование хака на основе JSON:

const myDeepCopy = JSON.parse(JSON.stringify(myOriginal));

Это обходное решение было настолько популярным, что в
движке JavaScript V8 был оптимизирован метод JSON.parse() и в особенности указанный выше паттерн,
чтобы сделать его работу максимально быстрой. Он действительно работает быстро,
но имеет ряд недостатков и подводных камней:
  • Рекурсивные структуры данных. Метод JSON.stringify() работает, когда ему задана рекурсивная структура данных. Это часто происходит при работе со связанными списками или деревьями.
  • Встроенные типы. Метод JSON.stringify() работает, если значение содержит другие встроенные объекты JS, такие как MapSetDateRegExp или ArrayBuffer.
Функции. Метод JSON.stringify() отклоняет функции.

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

Платформа уже давно нуждалась в возможности создавать глубокие копии значений JavaScript в ряде случаев: для хранения значения JS в IndexedDB требуется определенная сериализация, чтобы значение могло храниться на диске, потом десериализовано для восстановления значения JS. Точно так же для отправки сообщений в WebWorker с помощью postMessage() требуется перенести значение JS из одной области JS в другую. Используемый для этого алгоритм называется «структурный клон», и до недавнего времени он был практически недоступен для разработчиков.

Сейчас ситуация изменилась. Спецификация HTML была изменена так, чтобы выдавать функцию structuredClone(), которая выполняет именно этот алгоритм, нужный разработчикам для простого создания глубоких копий значений JavaScript.

Только и всего! Это весь API. Если вы хотите узнать подробности, посмотрите статью MDN.

Возможности и ограничения

Структурное клонирование устраняет многие (хотя и не все) недостатки метода JSON.stringify(). Структурное клонирование может обрабатывать циклические структуры данных, поддерживает многие встроенные типы данных и в целом работает более надежно и, как правило, быстрее.

Однако у него есть некоторые ограничения, которые могут стать для вас неожиданностью:

  • Прототипы. Если вы используете structuredClone() с экземпляром класса, то в качестве возвращаемого объекта вы получает основной объект, так как структурное клонирование отменяет цепочку прототипов объекта.

  • Функции. Если ваш объект содержит функции, они будут тихо удалены.

  • Неклонируемые значения. Для некоторых значений невозможно применить структурное клонирование, прежде всего для Error и узлам DOM. Попытка приведет к тому, что structuredClone() выдаст ошибку.

Если какие-либо из этих ограничений вам мешают, библиотеки, вроде Lodash, по-прежнему обеспечивают кастомную реализацию других алгоритмов глубокого копирования, которые могут подойти для вашего случая.

Производительность

Я не проводил нового сравнения показателей, но сравнивал разные методы в начале 2018 еще до появления structuredClone(). Тогда метод JSON.parse() был самым быстрым вариантом для очень маленьких объектов. Полагаю, что и сейчас это так. Методы, основанные на структурном клонировании, были (существенно) быстрее для более крупных объектов. Учитывая, что новый метод structuredClone() не нарушает работу других APIs и надежнее, чем JSON.parse(), я бы рекомендовал сделать его стандартным методом для глубокого копирования.

Заключение

Если вам нужно создать глубокую копию значения JS (например, потому что вы используете неизменяемые структуры данных или хотите, чтобы функция работала с объектом, не затрагивая оригинал), то вам больше не нужно искать обходные решения или библиотеки. Теперь в экосистеме JS есть structuredClone(). Ура!

Погрузитесь в изучение Java и освойте новые технологии на продвинутом уровне со скидкой 10%: https://ibs-training.ru/training/katalog_kursov/razrabotka_po_java/

Источник: https://web.dev/structured-clone/



Последние статьи в блоге

Как ИИ действительно влияет на продуктивность разработчика: неожиданные выводы из исследований

За последние пару лет у многих разработчиков в редакторах и IDE поселились новые «напарники» — всевозможные ИИ-инструменты. Обещания были впечатляющие: меньше рутины, быстрее релизы, код пишется почти сам. Но когда первые восторги улеглись и появились системные исследования, стало ясно: эффект от ИИ далеко не такой однозначный. Где-то он действительно ускоряет работу команд на 20%, а где-то, наоборот, тормозит опытных инженеров. И вот парадокс: даже там, где выигрыш в скорости очевиден, бизнес не всегда чувствует, что проекты двигаются быстрее.

Новости
08 сентября 2025

Сквозная логика: от бизнес-процесса к реализации без потерь

Главный принцип работы с проектной документацией — поддерживать её связность и актуальность. Любая, даже самая детальная схема (BPMN, Use Case, C4), мгновенно теряет ценность, если она конфликтует с другой. Узнаёте? Сначала все силы бросают на «личный кабинет», но после пары спринтов главным внезапно становятся «возвраты». В результате возникает опасный разрыв: цели проекта, реализуемый функционал и схемы, которые должны их описывать, живут своей жизнью. Документация превращается в «мёртвые зоны», которые больше не отражают реальность.

29 августа 2025

Заказная разработка ПО в IBS: безопасная разработка и доставка

В этой статье начальник отдела DevOps компании IBS Артур Галеев расскажет об опыте внедрения принципов безопасной разработки, используемых инструментах и нормативных актах, на которые стоит опираться.

Новости
26 августа 2025

Сертификация ИТ-специалистов: точная оценка ваших компетенций

В ИТ-мире важно не просто обладать знаниями, но и четко понимать свой реальный уровень владения теми или иными навыками.

Новости
22 августа 2025

Группа компаний IBS запускает национальную сертификацию для бизнес-аналитиков

Центр сертификации IBS запускает новую систему оценки квалификации бизнес-аналитиков, которая сочетает международные стандарты c особенностями российского рынка. Программа ориентирована на теоретическую базу и прикладные навыки, необходимые в работе бизнес-аналитика в современных ИТ- и цифровых проектах.

Жизнь компании
20 августа 2025

От разработчика к тренеру: как превратить экспертизу в стабильный доход

Часто к преподаванию переходят после достижения «карьерного потолка»: на уровне сеньора процессы отлажены, и новые вызовы исчезают. Однако вместо того чтобы долго преподавать за символическую плату, можно сосредоточиться на создании системного заработка. Разберём реальные способы: от коучинга до запуска курсов.

Новости
13 августа 2025

Установка и настройка брокера сообщений Kafka на Windows

Цель задания: научиться устанавливать и настраивать Apache Kafka на операционной системе Windows, а также выполнять базовые операции с топиками и сообщениями.

21 июля 2025

Почему Python? Полный разбор Python vs Java в ML

«Когда 9 из 10 курсов по машинному обучению используют Python — это не случайность. Это результат десятилетия эволюции инструментов, сообщества и образовательной экосистемы».

21 июля 2025

Что должен знать и уметь архитектор ПО в 2025 году

Представьте профессию, в которой нужно одновременно мыслить как инженер, говорить как консультант и чувствовать бизнес как продакт. Архитектор ПО — это не просто старший разработчик с модным названием должности, а человек, который соединяет технологии, людей и цели в устойчивую, масштабируемую систему. Но какими навыками он должен владеть сегодня, чтобы быть действительно востребованным?

21 июля 2025

Памятка по документированию архитектурных решений

Отсутствие качественного архитектурного описания в сложных ИТ-проектах создает серьезные риски: фрагментированное понимание системы, накопление «архитектурного долга», трудности интеграции, масштабирования и онбординга. Это ведет к срывам сроков, перерасходу бюджета, снижению качества и росту затрат на поддержку, подвергая проект риску неоптимальных решений и критических уязвимостей.

Новости
18 июля 2025

Летняя акция: учитесь онлайн с выгодой, не выходя из отпуска! До конца августа второй курс со скидкой 50%

Проведите лето с пользой для карьеры – второй курс со скидкой 50%!

09 июля 2025

5 курсов июля со скидкой 30%

Друзья, у нас остались последние места на курсах, которые стартуют в июле. Сейчас есть возможность записаться на обучение со скидкой 30%!

Новости
04 июля 2025

Карьерный трек аналитика: от базы к экспертизе

Системные и бизнес-аналитики аналитики играют ключевую роль в digital-развитии продуктов. Эти специалисты выступают связующим звеном между бизнес-задачами и техническими решениями, обеспечивая эффективную коммуникацию между заинтересованными сторонами. Рассмотрим карьерные пути в аналитике, актуальные требования рынка и перспективы профессионального роста.

27 июня 2025

Почему именно сейчас стоит учиться на бизнес-аналитика уровня Middle. «Руководство BABOK» в подарок участникам программы!

Вы в ИТ, вам за 30. Вроде бы всё хорошо — есть работа, скиллы, стабильность. Но в воздухе — тревожность. Проекты замораживаются. Бизнес урезает бюджеты. От ИТ ждут не просто задач, а конкретного влияния на прибыль.

25 июня 2025

Уничтожит ли ИИ-генератор кода профессию разработчика?

С появлением ИИ-инструментов, а также в связи недавним анонсом Canva Code, который генерирует код за пару кликов, многие задумались: не станут ли такие инструмент угрозой для разработчиков? Давайте разберемся, есть ли здесь реальные риски, или это все же преувеличения.

23 июня 2025

Проектное резюме консультанта 1С: карьерный инструмент, чтобы выделиться среди других кандидатов

Рассказываем о продвинутой альтернативе привычного резюме для консультантов 1C и других специалистов с проектной занятостью.

Новости
19 июня 2025

Выбор карьеры: Менеджер бизнес-процессов или Бизнес-аналитик уровня Middle?

В мире цифровой трансформации пути развития аналитиков и менеджеров проектов все чаще расходятся: кому-то ближе работа с требованиями и API, а кому-то — выстраивание системной эффективности на уровне всей компании. Какой путь выбрать лично вам?

Новости
18 июня 2025

В Учебном центре IBS планируется запуск курсов по продуктам TData

Читайте о стратегическом соглашении TData и IBS и наших новых курсах

11 июня 2025

Компетенции бизнес-аналитиков: Junior и Middle в сравнении

В условиях динамично развивающейся ИТ-индустрии важно чётко понимать, какие навыки и знания необходимы для успешной работы на каждом этапе карьерного пути. Сегодня обсудим разницу в компетенциях ИТ бизнес-аналитиков уровней Junior и Middle. Если вы только начинаете свой путь в ИТ бизнес-анализе или, наоборот, уже обладаете некоторым опытом, этот материал поможет вам понять, какие навыки необходимы на каждом уровне и как развиваться дальше.

Новости
05 июня 2025

Лимит на сбои. Как понять, что система перегружена, а не просто плохо сделана?

Оценить производительность системы непросто, а контролировать еще сложнее. Как сделать так, чтобы внедряемая или уже эксплуатируемая система справлялась с нагрузками? Можно ли в этом вопросе полностью положиться на разработчиков ПО или вендоров? И кто в итоге будет отвечать за все простои системы? Рассказывает Николай Марченко, директор отделения нагрузочного тестирования компании IBS. Начать следует с того, что разбираться с последствиями возможных сбоев в любом случае придется тем, кто работает непосредственно с системой. Поэтому о вопросах производительности лучше задуматься еще на этапе внедрения.

Новости
03 июня 2025

Не нашли, что искали? — Просто напишите, и мы поможем

Корпоративное обучение Оценка персонала Сертификация О нас Стань тренером Блог
Пользователь только что записался на курс ""
Спасибо!
Форма отправлена успешно.