Mamy tablicę [„javascript”, „jest”, „fajny”, 1, 2, 3]. Zobaczmy co się stanie, jeśli będziemy chcieli ją skopiować i przypisać do zmiennej, a następnie zmodyfikować tę skopiowaną tablicę:
Okazuje się, że zmianie uległy dane w obu tablicach! Dlaczego przy kopiowaniu tablic użycie znaku = nie zadziała?
W javascript wyróżniamy typy danych: proste i referencyjne.
Typy proste to:
string
number
boolean
null
undefined
Typy referencyjne to np:
obiekt
tablica
funkcja
Typy proste służą do zapisywania „prostych” danych, jak liczba, string albo inna z wyżej wymienionych danych. Jeśli więc przypiszemy do zmiennej number liczbę 5 (let number = 5), to w pamięci zapisana zostanie liczba 5.
Jednak w przypadku typów referencyjnych do zmiennych nie są przypisywane ich wartości lecz referencje. Oznacza to, że do zmiennej let arr = [1, 2, 3] nie jest przypisana wartość [1, 2, 3], ale adres do miejsca w pamięci, w którym ta wartość jest zapisana. Taki zabieg ma na celu zaoszczędzenie pamięci, ponieważ wartość dla arr zapisana jest tylko jeden raz, a odwoływać się do niej można z kilku miejsc w kodzie.
Kiedy więc zmiennej arr2 przypiszemy zmienną arr1, to kopiujemy referencję do obiektu, a nie sam obiekt (w naszym przypadku obiektem tym jest tablica). Teraz dwie zmienne – arr1 i arr2 odwołują się do tego samej tablicy, więc jeśli zmienimy wartość którejkolwiek z nich, zmieni się też wartość drugiej. Jak temu zaradzić?
Jak skopiować tablicę w javascript?
Wiemy już, że nie możemy uzyć znaku = do skopiowania wartości tablicy. Ale możemy wykorzystać inne sposoby:
ES 6 wprowadziło nowy sposób na kopowanie tablic, jest nim operator spread, czyli trzy kropki stawiane przed podaniem wartości, jakie chce się iterować do miejsca docelowego. Oznacza to, że pisząc …arr1 „wrzucasz” po kolei wszystkie wartości z arr1 do miejsca, w które chcesz je skopiować:
Wszystkie z wymienianych wyżej sposobów mają jednak wadę – mogą skopiować tablicę tylko na jednym poziomie (tzw. shallow copy – płytka kopia), więc NIE nadają się do kopiowania tablic wielowymiarowych.
let arr1 = [[1, 2, 3]];
let arr2 = arr1.slice();
// or let arr2 = […arr1];
// or let arr2 = [].concat(arr1);
// or let arr2 = Array.from(arr1);
arr2[0][1] = "super";
console.log(arr1); // [[1, "super", 3]]
console.log(arr2); // [[1, "super", 3]]
Kopiowanie tablic wielowymiarowych w javascript
Jeśli chcemy skopiować tablicę wielowymiarową, musimy napisać własną funkcję. Pomoże nam tu funkcja rekurencyjna – taka, która wywołuje samą siebie. Ilekroć nasza funkcja natrafi na zagnieżdżoną tablicę, wywoła się ponownie, aby skopiować każdy jej elemet. Do zwrócenia nowej tablicy użyjemy natomiast funkcji map();
Teraz możemy dowolnie zmieniać zagnieżdżone wartości w skopiowanej tablicy bez obawy, że pierwotna tablica ulegnie zmianie 🙂
Author: Joanna
Piszę kody, które (zazwyczaj) działają. Tresuję Wordpressa, kodzę z Reactem, zgłębiam świat DevOps i klikam w konsoli Linuxa. Hobbystycznie optymalizuję kod, bo lenistwo to najczystsza forma produktywności. Staram się nie zwariować między bugiem a deadlinem.