Głębokie klonowanie obiektów w JavaScript oznacza tworzenie całkowicie nowego obiektu, który jest identyczną kopią oryginału, ale nie ma żadnych odniesień do obiektów zawartych w oryginalnym obiekcie. Oto kilka wydajnych sposobów na głębokie klonowanie:
Użycie JSON.stringify i JSON.parse
Najprostszym (choć nie zawsze najbardziej wydajnym) sposobem na głębokie klonowanie obiektów jest użycie kombinacji `JSON.stringify()` do konwersji obiektu na ciąg JSON, a następnie `JSON.parse()` do przekształcenia tego ciągu z powrotem na nowy obiekt JavaScript.
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
Wada: Nie obsługuje funkcji, `Map`, `Set`, `RegExp`, `Date` i innych niestandardowych obiektów lub referencji cyklicznych.
Rekurencyjna Funkcja
Możesz napisać funkcję, która rekurencyjnie przechodzi przez wszystkie właściwości obiektu i kopiuje je do nowego obiektu.
function deepClone(obj, hash = new WeakMap()) {
if (obj === null) return null;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (typeof obj !== 'object') return obj;
if (hash.has(obj)) return hash.get(obj); // obsługa referencji cyklicznych
const result = Array.isArray(obj) ? [] : {};
hash.set(obj, result);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key], hash);
}
}
return result;
}
Wada: Może być mniej wydajna dla bardzo dużych lub złożonych obiektów.
Biblioteki Klonujące
Istnieje wiele bibliotek, które oferują wydajne i niezawodne funkcje do głębokiego klonowania, np. Lodash z metodą `_.cloneDeep(obj)`.
// Użycie Lodash
var cloned = _.cloneDeep(original);
Zaleta: Lodash i podobne biblioteki są optymalizowane dla różnych przypadków i mogą obsługiwać różnorodne typy danych.
Structured Clone Algorithm
W nowoczesnych przeglądarkach dostępna jest metoda `structuredClone()`, która umożliwia głębokie klonowanie obiektów.
const cloned = structuredClone(original);
Zaleta: Jest to natywna metoda przeglądarki, która jest bardzo wydajna i obsługuje wiele typów danych, w tym `Map`, `Set`, `ArrayBuffer`, `DataView`, `TypedArray`, `ImageBitmap`, `RegExp`, `Date` i niemal wszystko inne, co jest strukturalnie klonowalne.
MessageChannel
Metoda `MessageChannel` może być użyta do głębokiego klonowania poprzez asynchroniczne wysłanie obiektu przez kanał i natychmiastowe jego odebranie.
function deepClone(obj) {
return new Promise(resolve => {
const { port1, port2 } = new MessageChannel();
port2.onmessage = ev => resolve(ev.data);
port1.postMessage(obj);
});
}
Zaleta: Może być szybsza niż JSON dla dużych obiektów, ale nadal jest to rozwiązanie asynchroniczne.
Wybór metody zależy od kontekstu i wymagań. Jeśli obiekt jest prosty i nie zawiera specjalnych typów lub referencji cyklicznych, `JSON` może być wystarczający i łatwy w użyciu. Jeśli jednak potrzebujesz bardziej kompleksowego rozwiązania, `structuredClone`, biblioteki zewnętrzne lub wł
Komentarz