Skip to main content

structuredClone

structuredClone() це вбудована функція JavaScript, яка робить глибоку копію будь-якого значення, включно зі складними об'єктами, масивами, картами (Map) і навіть датами. Це найсучасніший і найбезпечніший спосіб клонувати дані в JS без сторонніх бібліотек.

Теорія

TL;DR

  • structuredClone(value) повертає повністю незалежну глибоку копію значення.
  • Усі вкладені об'єкти і масиви створюються заново, спільних посилань з оригіналом немає.
  • Підтримує Date, Map, Set, RegExp, ArrayBuffer, TypedArray, Blob, File.
  • Коректно обробляє циклічні посилання, на яких JSON.parse(JSON.stringify()) падає.
  • Не копіює функції, DOM-елементи, прототипи класів і символи.
  • Доступний у сучасних браузерах, у Node.js 17+ і в Deno.

Швидкий приклад

javascript
const clone = structuredClone(value);

Функція створює повністю незалежну копію об'єкта, включно з усіма вкладеними структурами, і повертає новий об'єкт без спільних посилань з оригіналом.

javascript
const user = { name: 'Alice', address: { city: 'Kyiv' }, hobbies: ['sport', 'music'] }; const clone = structuredClone(user); clone.address.city = 'Lviv'; clone.hobbies.push('coding'); console.log(user.address.city); // 'Kyiv' console.log(user.hobbies); // ['sport', 'music']

Копія глибока: усі вкладені об'єкти та масиви створюються заново, оригінал лишається незмінним.

Що вміє копіювати structuredClone

Підтримується:

  • об'єкти ({}) і масиви ([]);
  • вкладені структури будь-якої глибини;
  • Date;
  • Map, Set;
  • Blob, File, ArrayBuffer, TypedArray;
  • RegExp (зберігає шаблон і прапорці);
  • навіть циклічні посилання, на відміну від JSON.stringify().

Приклад з Map і Date:

javascript
const data = { date: new Date(), map: new Map([['a', 1], ['b', 2]]) }; const copy = structuredClone(data); console.log(copy.date === data.date); // false, це новий об'єкт console.log(copy.map.get('a')); // 1

Приклад з циклічним посиланням, який справді працює:

javascript
const obj = {}; obj.self = obj; const clone = structuredClone(obj); console.log(clone.self === clone); // true

structuredClone() дає раду навіть із самопосиланнями, там де JSON.parse(JSON.stringify()) просто впаде з помилкою.

Що не копіюється

Не підтримуються:

  • функції;
  • DOM-елементи;
  • класи та прототипи (об'єкт клонується як звичайний об'єкт, прототип втрачається);
  • Symbol;
  • значення, які алгоритм structured clone не вміє серіалізувати.
javascript
const obj = { fn: () => {}, el: document.body }; structuredClone(obj); // DataCloneError: function or DOM node cannot be cloned

Порівняння з іншими способами

МетодТип копіїКопіює вкладені даніКопіює функціїКопіює Date / Map / Set
{ ...obj }поверхневанітакні
Object.assign()поверхневанітакні
JSON.parse(JSON.stringify())глибокатакніні
structuredClone()глибокатакнітак
_.cloneDeep() (Lodash)глибокатакнітак

Підтримка середовищ

Працює:

  • в усіх сучасних браузерах (Chrome 98+, Firefox 94+, Edge 98+, Safari 15.4+);
  • у Node.js 17+;
  • у Deno.

Для старих середовищ можна підключити поліфіл, наприклад core-js:

bash
npm install core-js

Підсумкова таблиця властивостей:

ВластивістьstructuredClone()
Тип копіїглибока
Змінює оригіналні
Копіює об'єкти, масиви, Map, Set, Dateтак
Працює з циклічними посиланнямитак
Копіює функції та DOM-елементині
Вбудований і безпечнийтак

Типові помилки

  • Очікувати, що клон збереже клас. Екземпляр класу клонується як простий об'єкт: дані лишаються, прототип і методи зникають, тож clone instanceof User буде false.
  • Передавати об'єкт з методом або колбеком. Одна функція десь усередині структури валить увесь виклик з DataCloneError, а не пропускається мовчки.
  • Плутати з поверхневим копіюванням. { ...obj } і Object.assign() клонують лише верхній рівень, тому вкладені об'єкти лишаються спільними.
  • Вважати JSON.parse(JSON.stringify()) рівноцінною заміною. Він губить undefined і функції, перетворює Date на рядок, ламає Map і Set та падає на циклах.
  • Забувати про старі середовища. У Node.js 16 і нижче та в старих браузерах функції просто немає, тому потрібен поліфіл або перевірка наявності.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.