Tablica jednowymiarowa może być płytko lub głęboko sklonowana, tylko w tym przypadku nie ma różnicy, bo masz tylko jedną operację faktycznego klonowania.
JSON.parse(JSON.stringify())
jest bardzo powolną metodą, w dodatku zgubi część danych (w json nie zapiszesz funkcji, undefined
, obiektów będących instancjami czegoś innego niż Object). Lepszą opcją byłaby pętla i rekurencja, ale najpierw pasowałoby, żebyś zrozumiał to, co robisz. Przedstawię to na obrazku:
Mamy na początku tablicę A, zawierającą dwie kolejne tablice: B i C.
Gdy wykonujesz kopiowanie płytkie - tworzysz nową tablicę D - jest ona taka sama jak A, ale nie ta sama. Pierwotnie obie zawierają te same, nie takie same elementy B i C. Jeżeli dodasz coś do tablicy A to nie będzie tego w tablicy D i odwrotnie. Ale jeżeli dodasz coś do tablicy B - to odczytując tablicę B zarówno poprzez A i D otrzymasz to samo. Czyli modyfikować tablicę B możesz teraz na 3 sposoby: B.push()
, A[0].push()
i D[0].push()
. I tak samo odczytywać.
Prosta forma na "ręczne" skopiowanie wyglądałaby tak:
const A = [];
const B = [0, 1];
const C = [2, 3];
A.push(B, C);
const D = []; // nowa tablica
D.push(B, C); // wepchanie TYCH SAMYCH elementów
Zaproponowane przez Ciebie na początku D = A
nie tworzy nowej tablicy, tylko nadaje drugą nazwę tej samej tablicy.
Formą sprawdzenia czy tablica jest tą samą, a nie taką samą jest użycie operatora ===
.
A[0] === B[0]; /// true
Klonowanie głębokie różni się tym, że każdy element wgłąb (nawet jakby zagnieżdżenie tablic było jeszcze większe) jest taki sam, ale nie ten sam.
W kolejnym "prostym" kodzie posłużę się skróconym zapisem [...tablica]
, który tworzy nową tablicę, jednocześnie wypełniając ją wartościami z tej tablicy. Ale zanim do niego przejdziemy zaznaczę, że:
const A = [];
const B = [0, 1];
const C = [2, 3];
A.push(B, C);
const D = [...A];
Nadal sprawi, że tablice B i C są w dwóch tablicach A i D, ale to są dokładnie te same tablice.
Prosty przykład "ręczny" głębokiego kopiowania:
const A = [];
const B = [0, 1];
const C = [2, 3];
A.push(B, C);
const D = []; // nie wypełniamy zawartością, bo chcemy mieć też kopie B i C.
const E = [...B]; // robimy kopię wewnątrznych tablic
const F = [...C];
const D = [];
D.push(E, F);
Użyj ===
, żeby sprawdzić, że faktycznie - choć E wygląda tak samo jak B - to są to różne tablice. Modyfikując jedną nie zmieniasz zawartości drugiej.