Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «structuredClone». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`structuredClone()` це вбудована функція JavaScript, яка робить глибоку (deep) копію значення разом з усіма вкладеними структурами, без спільних посилань з оригіналом.** Вона вміє `Date`, `Map`, `Set`, `RegExp`, `ArrayBuffer`, `Blob`, `File` і навіть циклічні посилання, на яких `JSON.stringify()` падає. Не копіюються функції, DOM-вузли, символи та прототипи класів: на них кидається `DataCloneError`. ```javascript const obj = {}; obj.self = obj; // циклічне посилання const clone = structuredClone(obj); console.log(clone.self === clone); // true ``` **Ключове:** це найсучасніший вбудований спосіб глибокого клонування даних у JS без сторонніх бібліотек, але він працює лише з даними, а не з поведінкою.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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 і нижче та в старих браузерах функції просто немає, тому потрібен поліфіл або перевірка наявності.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.