Okładka artykułu: Klonowanie obiektów

Klonowanie obiektów

Klonowanie obiektów w JS

Podstawowe koncepcje

W JavaScript obiekty są przekazywane przez referencję, a nie przez wartość. Oznacza to, że kiedy przypisujesz obiekt do nowej zmiennej, obie zmienne wskazują na ten sam obiekt w pamięci:

const original = { a: 1, b: 2 };
const copy = original; // To nie jest klonowanie, tylko kopia referencji
copy.a = 100;
console.log(original.a); // 100 - oryginalny obiekt został zmodyfikowany

Rodzaje klonowania

1. Płytkie klonowanie (Shallow Copy)

Tworzy nowy obiekt, ale właściwości, które są obiektami, wciąż wskazują na te same obiekty co w oryginale. Metody płytkiego klonowania:

  • Object.assign():
const original = { a: 1, b: { c: 2 } };
const clone = Object.assign({}, original);
clone.a = 100;
clone.b.c = 200;
console.log(original.a); // 1 - wartość prymitywna została skopiowana
console.log(original.b.c); // 200 - zagnieżdżony obiekt został zmodyfikowany
  • Operator rozwinięcia (spread operator):
const original = { a: 1, b: { c: 2 } };
const clone = { ...original };
  • Array.slice() (dla tablic):
const array = [1, 2, [3, 4]];
const clone = array.slice();

2. Głębokie klonowanie (Deep Copy)

Tworzy całkowicie niezależną kopię, gdzie wszystkie zagnieżdżone obiekty są również klonowane. Metody głębokiego klonowania:

  • JSON.parse (JSON.stringify()):
const original = { a: 1, b: { c: 2 } };
const clone = JSON.parse(JSON.stringify(original));
clone.b.c = 200;
console.log(original.b.c); // 2 - oryginalny obiekt nie został zmieniony

Ograniczenia tej metody:

  • Nie obsługuje funkcji
  • Nie obsługuje wartości undefined
  • Nie obsługuje obiektów cyklicznych
  • Nie obsługuje instancji Map, Set, Date (konwertuje daty na stringi)

Może prowadzić do problemów z wydajnością dla dużych obiektów

  • Biblioteki zewnętrzne:
// Lodash
const clone = _.cloneDeep(original);
  • structuredClone() - nowa metoda natywna

Od 2022 roku (wbudowane w przeglądarki i Node.js >=17), JavaScript wprowadził natywną metodę do głębokiego klonowania:

const original = { a: 1, b: { c: 2 }, d: new Date() };
const clone = structuredClone(original);

Zalety structuredClone():

  • Obsługuje obiekty cykliczne
  • Obsługuje większość wbudowanych typów (Map, Set, Date, ArrayBuffer, etc.)
  • Natywna metoda (nie wymaga importowania bibliotek)

Ograniczenia:

  • Nie obsługuje funkcji
  • Nie obsługuje DOM nodes

Porównanie metod klonowania

MetodaTyp klonowaniaZaletyWady
= (przypisanie)Kopia referencjiSzybkieNie jest klonowaniem
Object.assign()PłytkieProste, szybkieNie klonuje zagnieżdżonych obiektów
Spread {...obj}PłytkieCzytelna składniaNie klonuje zagnieżdżonych obiektów
JSON.parse/stringifyGłębokieNie wymaga bibliotekNie obsługuje funkcji, cykli, specjalnych obiektów
structuredClone()GłębokieNatywne, obsługuje cykleNie obsługuje funkcji
Biblioteki (lodash)GłębokieWszechstronneWymaga dodatkowej zależności