Метод structuredClone()
та оператор поширення (...
) — це два різні способи копіювання об'єктів або масивів у JavaScript, але вони мають різні поведінки та сфери використання.
До появи structuredClone()
розробники зазвичай використовували техніки, такі як JSON.parse(JSON.stringify(data))
для глибокого копіювання, які мали обмеження з особливими типами даних (наприклад, Date
, Map
, Set
) та функціями.
1. structuredClone()
:
structuredClone()
— це вбудований метод, який виконує глибоке копіювання значення. Він був введений в JavaScript (ECMAScript) як частина HTML Living Standard у 2021 році. Він був доданий до Web APIs і тепер підтримується сучасними веб-браузерами.- Він рекурсивно копіює всі вкладені об'єкти та масиви, забезпечуючи, щоб зміни в скопійованих даних не впливали на оригінал.
- Підтримує складні типи даних: Може копіювати об'єкти, що містять більш складні типи даних, такі як
Map
,Set
,ArrayBuffer
та навіть кругові посилання. - Зберігає структури даних і працює з такими типами, як
Date
,RegExp
таTypedArray
.
const original = {
name: 'Alice',
address: { city: 'Wonderland' },
hobbies: ['reading', 'chess']
};
// Глибоке копіювання оригінального об'єкта
const cloned = structuredClone(original);
// Зміни в скопійованому об'єкті не впливають на оригінал
cloned.address.city = 'Looking-Glass Land';
cloned.hobbies.push('painting');
console.log(original.address.city); // Виведеться: Wonderland
console.log(original.hobbies); // Виведеться: ['reading', 'chess']
console.log(cloned.address.city); // Виведеться: Looking-Glass Land
console.log(cloned.hobbies); // Виведеться: ['reading', 'chess', 'painting']
2. Оператор поширення (...
):
- Оператор поширення виконує поверхневе копіювання об'єкта чи масиву.
- Він копіює лише властивості верхнього рівня, а не вкладені об'єкти. Якщо об'єкт містить вкладені об'єкти, вони будуть посиланнями, а не повністю скопійовані.
- Поверхневе копіювання означає, що зміни у вкладених об'єктах чи масивах у скопійованій версії впливатимуть на оригінальний об'єкт, і навпаки.
const original = {
name: 'Alice',
address: { city: 'Wonderland' },
hobbies: ['reading', 'chess']
};
// Поверхневе копіювання за допомогою оператора поширення
const shallowCopy = { ...original };
// Зміни в поверхневому копіюванні впливають на оригінал
shallowCopy.address.city = 'Looking-Glass Land';
shallowCopy.hobbies.push('painting');
console.log(original.address.city); // Виведеться: Looking-Glass Land
console.log(original.hobbies); // Виведеться: ['reading', 'chess', 'painting']
console.log(shallowCopy.address.city); // Виведеться: Looking-Glass Land
console.log(shallowCopy.hobbies); // Виведеться: ['reading', 'chess', 'painting']
Основні відмінності між structuredClone()
та оператором поширення:
┌────────────────────────────────┬────────────────────────────────────────────────────┬────────────────────────────────────────────────────────┐
│ Аспект │ structuredClone() │ Оператор поширення (...) │
├────────────────────────────────┼────────────────────────────────────────────────────┼────────────────────────────────────────────────────────┤
│ Тип копії │ Глибоке копіювання │ Поверхневе копіювання │
│ Вкладені об'єкти │ Рекурсивно копіює вкладені об'єкти/масиви │ Копіює посилання на вкладені об'єкти/масиви │
│ Обробка спеціальних типів даних │ Підтримує копіювання `Map`, `Set`, `Date`, `ArrayBuffer` тощо.
│ Не може обробляти складні типи, копіює їх поверхнево │
│ Кругові посилання │ Може обробляти кругові посилання │ Не може обробляти кругові посилання, викликає помилку │
│ Збереження даних │ Зберігає структуру та типи (наприклад, Date, RegExp) │ Може не зберегти спеціальні типи так, як очікується │
│ Продуктивність │ Трохи повільніше через глибоке копіювання │ Швидший для простих або плоских структур │
└────────────────────────────────┴────────────────────────────────────────────────────┴────────────────────────────────────────────────────────┘
Варіанти використання кожного методу:
structuredClone()
:
- Використовуйте, коли вам потрібне глибоке копіювання об'єкта чи масиву.
- Корисно для копіювання складних структур даних (наприклад, вкладених об'єктів, мап, сетів).
- Ідеально підходить, коли потрібно забезпечити повне відокремлення між оригіналом і копією.
Оператор поширення (...
):
- Підходить для поверхневого копіювання об'єктів/масивів, що є плоскими або не мають вкладених структур.
- Корисно для злиття об'єктів, коли потрібно копіювати лише властивості верхнього рівня.
- Ідеально підходить, коли потрібна швидка копія, і ви не проти, якщо посилання на вкладені об'єкти будуть спільними.
Висновок:
structuredClone()
підходить для глибокого копіювання, тому, коли потрібно зберегти всю структуру і забезпечити повне відокремлення від оригіналу.- Оператор поширення підходить для поверхневого копіювання, особливо коли працюєте з простими об'єктами та плоскими структурами даних.
Перекладено з: Shallow copy vs deep copy >> Spread operator vs structuredClone()