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.
Швидкий приклад
const clone = structuredClone(value);Функція створює повністю незалежну копію об'єкта, включно з усіма вкладеними структурами, і повертає новий об'єкт без спільних посилань з оригіналом.
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:
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Приклад з циклічним посиланням, який справді працює:
const obj = {};
obj.self = obj;
const clone = structuredClone(obj);
console.log(clone.self === clone); // truestructuredClone() дає раду навіть із самопосиланнями, там де JSON.parse(JSON.stringify()) просто впаде з помилкою.
Що не копіюється
Не підтримуються:
- функції;
- DOM-елементи;
- класи та прототипи (об'єкт клонується як звичайний об'єкт, прототип втрачається);
- Symbol;
- значення, які алгоритм structured clone не вміє серіалізувати.
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:
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 і нижче та в старих браузерах функції просто немає, тому потрібен поліфіл або перевірка наявності.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.