Kurs JavaScript i TypeScript · Moduł 5: Zaawansowany JavaScript

Podstawowe metody tablic

5 min czytania
W tej lekcji4

Stado raptorów nigdy nie stoi w miejscu: rano do wybiegu dołącza nowy osobnik, wieczorem jeden trafia do weterynarza, a ktoś inny musi przejść na początek kolejki do karmienia. Budowanie tablicy od nowa przy każdej takiej zmianie byłoby męczące i łatwo przy tym zgubić dinozaura. JavaScript oferuje szereg wbudowanych metod, które pozwalają dodawać, usuwać i modyfikować elementy tablicy. W kontekście Parku Jurajskiego potrzebujemy ich do zarządzania listami dinozaurów, ich statusem i lokalizacją.

Metody modyfikujące tablicę (mutujące)

Pierwsza grupa metod zmienia tablicę w miejscu. Efekt ich działania zobaczy każdy fragment kodu, który korzysta z tej samej tablicy.

push() - dodawanie na koniec

Metoda push() dodaje jeden lub więcej elementów na koniec tablicy i zwraca nową długość tablicy:

1const pack = ["Blue", "Charlie"];
2console.log(pack.length); // 2
3
4pack.push("Delta");
5console.log(pack); // ["Blue", "Charlie", "Delta"]
6
7// Dodawanie wielu elementów naraz
8pack.push("Echo", "Fox");
9console.log(pack); // ["Blue", "Charlie", "Delta", "Echo", "Fox"]

Stado urosło, choć zadeklarowaliśmy je przez const - stała pilnuje przypisania, a nie zawartości tablicy. Pamiętaj też, że push() zwraca liczbę, a nie tablicę, więc jej wyniku nie traktuj jak nowego stada.

pop() - usuwanie z końca

Metoda pop() działa odwrotnie: usuwa ostatni element z tablicy i zwraca go, więc od razu wiesz, kto opuścił stado:

1const pack = ["Blue", "Charlie", "Delta", "Echo"];
2const removed = pack.pop();
3
4console.log(removed); // "Echo"
5console.log(pack);    // ["Blue", "Charlie", "Delta"]

Echo znika z tablicy, ale trafia do zmiennej removed, więc wpis można od razu przekazać weterynarzowi. Na pustej tablicy pop() nie zgłosi błędu, tylko zwróci undefined.

unshift() - dodawanie na początek

Metoda unshift() dodaje elementy na początek tablicy, przesuwając wszystkie dotychczasowe elementy o pozycję dalej:

1const pack = ["Charlie", "Delta"];
2pack.unshift("Blue");
3
4console.log(pack); // ["Blue", "Charlie", "Delta"]

Blue ma teraz indeks 0, a Charlie przesuwa się na 1. Podobnie jak push(), także unshift() zwraca nową długość tablicy.

shift() - usuwanie z początku

Metoda shift() usuwa pierwszy element z tablicy i zwraca go. To naturalny wybór, gdy obsługujesz kolejkę do karmienia od początku:

1const pack = ["Blue", "Charlie", "Delta"];
2const first = pack.shift();
3
4console.log(first); // "Blue"
5console.log(pack);  // ["Charlie", "Delta"]

Nazwy łatwo pomylić, więc zapamiętaj parę: shift() zabiera z początku, a unshift() dokłada na początek. Obie przenumerowują wszystkie pozostałe elementy.

splice() - wszechstronne modyfikowanie

Metoda splice() może dodawać, usuwać lub zamieniać elementy w dowolnym miejscu tablicy. Modyfikuje oryginalną tablicę. Przyjmuje indeks startowy, liczbę elementów do usunięcia i opcjonalnie nowe elementy:

1const dinosaurs = ["T-Rex", "Velociraptor", "Stegosaurus", "Triceratops"];
2
3// Usunięcie 1 elementu od indeksu 1
4dinosaurs.splice(1, 1);
5console.log(dinosaurs); // ["T-Rex", "Stegosaurus", "Triceratops"]
6
7// Wstawienie elementu na indeks 1 (bez usuwania)
8dinosaurs.splice(1, 0, "Brachiosaurus");
9console.log(dinosaurs); // ["T-Rex", "Brachiosaurus", "Stegosaurus", "Triceratops"]
10
11// Zamiana elementu na indeksie 2
12dinosaurs.splice(2, 1, "Pteranodon");
13console.log(dinosaurs); // ["T-Rex", "Brachiosaurus", "Pteranodon", "Triceratops"]

Każde wywołanie zwraca tablicę usuniętych elementów - pierwsze oddałoby ["Velociraptor"]. Drugie pokazuje, że liczba usuwanych elementów równa zero oznacza czyste wstawienie, a trzecie łączy usunięcie ze wstawieniem, czyli zamianę.

Jedno stado, dwie nazwy

Zanim przejdziemy do metod, które nie mutują, poznaj pułapkę. Przypisanie tablicy do nowej zmiennej nie tworzy kopii, tylko drugą nazwę dla tego samego stada:

1const pack = ["Blue", "Charlie"];
2const nightShift = pack; // ta sama tablica, nie kopia
3
4nightShift.push("Delta");
5console.log(pack);                // ["Blue", "Charlie", "Delta"]
6console.log(nightShift === pack); // true

Zmiana przez jedną nazwę jest widoczna pod drugą, bo obie zmienne przechowują referencję, czyli wskazanie na tę samą tablicę w pamięci. Tak wygląda cykl życia danych: silnik rezerwuje pamięć przy tworzeniu tablicy, kod korzysta z niej przez referencje, a gdy tablica przestaje być osiągalna, garbage collector sam ją zwalnia. Szczegóły poznasz w lokacji o zarządzaniu pamięcią.

Metody niemodyfikujące (niemutujące)

slice() - kopiowanie fragmentu tablicy

Metoda slice() zwraca nową tablicę będącą fragmentem oryginalnej. Nie modyfikuje oryginału. Drugi argument to indeks, przed którym kopiowanie się zatrzymuje:

1const allDinos = ["T-Rex", "Velociraptor", "Stegosaurus", "Triceratops", "Pteranodon"];
2
3// slice(start, end) - od indeksu start do end (bez end)
4const herbivores = allDinos.slice(2, 4);
5console.log(herbivores); // ["Stegosaurus", "Triceratops"]
6console.log(allDinos);   // Oryginał niezmieniony!
7
8// Kopiowanie całej tablicy
9const copy = allDinos.slice();
10console.log(copy); // ["T-Rex", "Velociraptor", "Stegosaurus", "Triceratops", "Pteranodon"]

Element o indeksie końcowym nie trafia do wyniku, dlatego slice(2, 4) zwraca dwa dinozaury. Wywołanie bez argumentów kopiuje całą tablicę - to lekarstwo na pułapkę z referencjami. Kopia jest jednak płytka: obiekty w środku pozostają wspólne.

Kluczowa różnica: splice() vs slice()

Cechasplice()slice()
MutacjaTAK - zmienia oryginalną tablicęNIE - zwraca nową tablicę
Parametry(start, deleteCount, ...items)(start, end)
ZastosowanieDodawanie/usuwanie/zamiana elementówWycinanie fragmentu tablicy

Nazwy różnią się jedną literą, a działaniem wszystkim: splice() przestawia stado, slice() robi zdjęcie jego fragmentu. Gdy nie musisz zmieniać oryginału, polecam slice() - kod bez niespodziewanych mutacji łatwiej śledzić.

Łańcuchy metod: map, filter i forEach

Metody niemutujące mają jeszcze jedną zaletę: skoro zwracają nową tablicę, na wyniku można od razu wywołać kolejną metodę. Tak powstaje łańcuch. Najczęściej spotkasz w nim trzy metody - map() przekształca każdy element, filter() zostawia tylko pasujące, a forEach() wykonuje akcję dla każdego:

1const pack = ["Blue", "Charlie", "Delta", "Echo"];
2
3const tags = pack.map(name => name.toUpperCase());
4console.log(tags); // ["BLUE", "CHARLIE", "DELTA", "ECHO"]
5
6const longNames = pack.filter(name => name.length > 4);
7console.log(longNames); // ["Charlie", "Delta"]
8
9// Łańcuch: najpierw filtr, potem transformacja
10const alarms = pack.filter(name => name.length > 4).map(name => name + "!");
11console.log(alarms); // ["Charlie!", "Delta!"]
12
13pack.forEach(name => console.log("Obecny:", name)); // zwraca undefined
14console.log(pack); // ["Blue", "Charlie", "Delta", "Echo"] - bez zmian

map() zawsze zwraca nową tablicę tej samej długości, a filter() - krótszą lub równą. forEach() zwraca tylko undefined, więc za nim łańcucha nie da się kontynuować. Ostatnia linijka potwierdza, że oryginalne stado zostało nietknięte. Czwarta metoda, reduce(), zwija tablicę do jednej wartości - zajmiemy się nią w następnej lekcji.

W laboratorium poniżej przećwiczysz dodawanie i usuwanie raptorów, a potem splice() i slice().

Pamiętaj: metody mutujące przestawiają stado na wybiegu, a niemutujące robią mu zdjęcie, nie ruszając ani jednego raptora.

Kod do tej lekcji: index.js
1// Podstawowe metody tablic - Zarzadzanie stadem raptorów
2
3const pack = ["Blue", "Charlie"];
4console.log("Poczatkowe stado:", pack);
5
6// push() - dodaj na koniec
7pack.push("Delta");
8console.log("Po push('Delta'):", pack);
9
10// pop() - usun z konca
11const removed = pack.pop();
12console.log("Po pop():", pack, "| Usuniety:", removed);
13
14// unshift() - dodaj na poczatek
15pack.unshift("Alpha");
16console.log("Po unshift('Alpha'):", pack);
17
18// shift() - usun z poczatku
19const first = pack.shift();
20console.log("Po shift():", pack, "| Usuniety:", first);
21
22// === CWICZENIE ===
23// TODO: Stworz tablice dinosaurs z 5 dinozaurami
24const dinosaurs = ["T-Rex", "Velociraptor", "Stegosaurus", "Triceratops", "Pteranodon"];
25
26// TODO: Uzyj splice() do usuniecia 1 elementu od indeksu 2
27// TODO: Uzyj splice() do wstawienia "Brachiosaurus" na indeks 1
28
29console.log("\n=== splice() ===");
30console.log("Po operacjach splice:", dinosaurs);
31
32// TODO: Uzyj slice() do wyciecia elementow od indeksu 1 do 3
33// Pamietaj: slice() NIE modyfikuje oryginalnej tablicy!
34const fragment = dinosaurs.slice(1, 3);
35console.log("\n=== slice() ===");
36console.log("Fragment:", fragment);
37console.log("Oryginal niezmieniony:", dinosaurs);

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Co robi metoda push() w tablicy JavaScript?

  2. 2. Jaka jest różnica między shift() a unshift() w tablicach?

To 2 z 4 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Edytor kodu

    Utwórz tablicę pack i dodaj/usuń Velociraptory używając push, pop, shift, unshift.

  • Układanie w pionie

    Ułóż składnię tworzenia obiektu z zagnieżdżoną tablicą:

Przydatne artykuły