Kurs JavaScript i TypeScript · Moduł 2: Funkcje, tablice i obiekty

Funkcje strzałkowe (arrow functions)

8 min czytania
W tej lekcji7

Witaj ponownie w Parku Jurajskim! Dzisiaj poznamy funkcje strzałkowe (arrow functions) - nowoczesny sposób tworzenia funkcji w JavaScript, który został wprowadzony w ES6. Funkcje strzałkowe są bardziej zwięzłe niż tradycyjne wyrażenia funkcyjne i mają kilka unikalnych właściwości, które czynią je niezwykle przydatnymi w codziennej pracy.

Podstawowa składnia funkcji strzałkowych

Funkcje strzałkowe mają bardziej zwięzłą składnię niż tradycyjne funkcje. Porównajmy:

Tradycyjna funkcja:

1// Tradycyjna funkcja anonimowa
2const identifyDinosaur = function(species) {
3  return "Zidentyfikowano gatunek: " + species;
4};

Funkcja strzałkowa:

1// Funkcja strzałkowa
2const identifyDinosaur = (species) => {
3  return "Zidentyfikowano gatunek: " + species;
4};

Widzimy, że funkcja strzałkowa:

  1. Nie używa słowa kluczowego function
  2. Używa znaku strzałki => między parametrami a ciałem funkcji

Jeszcze większa zwięzłość

Funkcje strzałkowe oferują jeszcze bardziej skróconą składnię w następujących przypadkach:

Jeden parametr: można pominąć nawiasy

1// Z nawiasami
2const getSpeciesInfo = (species) => {
3  return `Gatunek ${species} został znaleziony w bazie danych.`;
4};
5
6// Bez nawiasów - to samo
7const getSpeciesInfoShort = species => {
8  return `Gatunek ${species} został znaleziony w bazie danych.`;
9};

Funkcja jednolinijkowa: niejawny return

Jeśli ciało funkcji składa się tylko z jednego wyrażenia zwracającego wartość, możemy pominąć nawiasy klamrowe i słowo kluczowe return:

1// Z return
2const getSpeciesAge = (species) => {
3  return species === "Tyrannosaurus" ? "68 milionów lat" : "Wiek nieznany";
4};
5
6// Z niejawnym return - to samo
7const getSpeciesAgeShort = (species) => species === "Tyrannosaurus" ? "68 milionów lat" : "Wiek nieznany";

Zwracanie obiektu

Przy zwracaniu obiektu musimy użyć nawiasów okrągłych wokół obiektu, aby nie był on interpretowany jako blok kodu:

1// Niepoprawne - JavaScript pomyśli, że to blok kodu
2// const getDinoData = (name, species) => { name: name, species: species };
3
4// Poprawne - obiekt otoczony nawiasami
5const getDinoData = (name, species) => ({ name: name, species: species });
6
7const blue = getDinoData("Blue", "Velociraptor");
8console.log(blue); // { name: "Blue", species: "Velociraptor" }

Praktyczne zastosowania funkcji strzałkowych

1. Przetwarzanie kolekcji danych

Funkcje strzałkowe są szczególnie przydatne przy metodach tablic takich jak map, filter, reduce:

1// Lista dinozaurów
2const dinosaurs = [
3  { name: "Rex", species: "Tyrannosaurus", carnivore: true, weight: 7000 },
4  { name: "Spike", species: "Stegosaurus", carnivore: false, weight: 5000 },
5  { name: "Blue", species: "Velociraptor", carnivore: true, weight: 100 },
6  { name: "Trixie", species: "Triceratops", carnivore: false, weight: 8000 }
7];
8
9// Filtrowanie drapieżników
10const carnivores = dinosaurs.filter(dino => dino.carnivore);
11
12// Mapowanie na nazwy gatunków
13const speciesList = dinosaurs.map(dino => dino.species);
14
15// Obliczanie łącznej wagi wszystkich dinozaurów
16const totalWeight = dinosaurs.reduce((sum, dino) => sum + dino.weight, 0);
17
18console.log("Drapieżniki:", carnivores.length);
19console.log("Gatunki:", speciesList.join(", "));
20console.log("Łączna waga:", totalWeight, "kg");

2. Obiekty z metodami

Funkcje strzałkowe przydają się wewnątrz metod obiektu, np. jako funkcje zwrotne w setInterval, bo zachowują this metody (o czym więcej nieco później):

1const dinoMonitor = {
2  dinosaurs: ["T-Rex", "Velociraptor", "Triceratops"],
3  lastUpdated: null,
4
5  init() {
6    this.update();
7
8    // Ustaw aktualizację co 60 sekund
9    setInterval(() => {
10      this.update();
11      console.log("Monitor zaktualizowany");
12    }, 60000);
13  },
14
15  update() {
16    this.lastUpdated = new Date().toISOString();
17    console.log(`Monitorowane dinozaury: ${this.dinosaurs.join(", ")}`);
18  }
19};
20
21dinoMonitor.init();

Kluczowa różnica: zachowanie this

Najważniejszą różnicą między funkcjami strzałkowymi a tradycyjnymi funkcjami jest sposób, w jaki wiążą one kontekst this.

Funkcje tradycyjne: dynamiczne wiązanie this

W tradycyjnych funkcjach, this jest określane w momencie wywołania funkcji i może się zmieniać:

1function DinoTracker() {
2  this.zone = "Nieznana";
3
4  this.updateZone = function(newZone) {
5    this.zone = newZone;
6    console.log(`Strefa: ${this.zone}`);
7  };
8
9  // Problem: 'this' w zwykłej funkcji przekazanej do setInterval nie wskazuje na DinoTracker (w przeglądarce to window, w Node.js obiekt Timeout)
10  setInterval(function() {
11    console.log(`Aktualna strefa: ${this.zone}`); // undefined
12  }, 1000);
13}
14
15const tracker = new DinoTracker();
16tracker.updateZone("Zagroda A");

Funkcje strzałkowe: leksykalne wiązanie this

Funkcje strzałkowe nie mają własnego this. Zamiast tego, dziedziczą this z zakresu, w którym zostały zdefiniowane (tzw. wiązanie leksykalne):

1function DinoTracker() {
2  this.zone = "Nieznana";
3
4  this.updateZone = function(newZone) {
5    this.zone = newZone;
6    console.log(`Strefa: ${this.zone}`);
7  };
8
9  // Rozwiązanie: funkcja strzałkowa zachowuje 'this' z otaczającego zakresu
10  setInterval(() => {
11    console.log(`Aktualna strefa: ${this.zone}`); // Działa!
12  }, 1000);
13}
14
15const tracker = new DinoTracker();
16tracker.updateZone("Zagroda A");

Kiedy NIE używać funkcji strzałkowych

Mimo swoich zalet, funkcje strzałkowe nie są odpowiednie we wszystkich sytuacjach:

1. Metody obiektu (gdy potrzebujemy własnego this)

1// ŹLE - funkcja strzałkowa nie ma własnego 'this'
2const dinoBad = {
3  name: "Blue",
4  introduce: () => {
5    console.log(`Cześć, jestem ${this.name}`); // this nie wskazuje na obiekt dino, więc imienia Blue tu nie zobaczysz
6  }
7};
8
9// DOBRZE - tradycyjna funkcja ma własny kontekst 'this'
10const dinoGood = {
11  name: "Blue",
12  introduce: function() {
13    console.log(`Cześć, jestem ${this.name}`); // Działa!
14  }
15};
16
17// DOBRZE - skrócona składnia metod w ES6
18const dinoShort = {
19  name: "Blue",
20  introduce() {
21    console.log(`Cześć, jestem ${this.name}`); // Też działa!
22  }
23};

2. Funkcje konstruktora (gdy używamy new)

1// ŹLE - funkcje strzałkowe nie mogą być konstruktorami
2const DinosaurArrow = (name, species) => {
3  this.name = name;
4  this.species = species;
5};
6
7// Spowoduje błąd:
8// const rex = new DinosaurArrow("Rex", "Tyrannosaurus");
9
10// DOBRZE - tradycyjna funkcja jako konstruktor
11function Dinosaur(name, species) {
12  this.name = name;
13  this.species = species;
14}
15
16const rex = new Dinosaur("Rex", "Tyrannosaurus");
17console.log(rex); // Dinosaur { name: "Rex", species: "Tyrannosaurus" }

3. Gdy potrzebujemy obiektu arguments

1// ŹLE - funkcje strzałkowe nie mają własnego obiektu 'arguments'
2const logArgsArrow = () => {
3  console.log(arguments); // ReferenceError albo arguments funkcji otaczającej
4};
5
6// DOBRZE - tradycyjna funkcja ma własny obiekt 'arguments'
7function logArgsRegular() {
8  console.log(arguments); // obiekt podobny do tablicy z argumentami
9}
10
11// Alternatywnie w ES6 - użyj parametru rest
12const logArgsRest = (...args) => {
13  console.log(args); // tablica z argumentami
14};

Praktyczny przykład: System monitorowania parku

Stwórzmy kompletny przykład systemu monitorowania Parku Jurajskiego, wykorzystując funkcje strzałkowe i ich unikalne właściwości:

1const parkMonitoringSystem = {
2  // Stan systemu
3  status: "Offline",
4  dinosaurs: [],
5  sectors: [],
6  securityAlerts: [],
7
8  // Inicjalizacja systemu
9  initialize() {
10    this.status = "Uruchamianie";
11
12    // Funkcja pomocnicza z zachowaniem kontekstu this
13    const loadConfigs = () => {
14      // Symulacja ładowania konfiguracji
15      console.log("Ładowanie konfiguracji systemu...");
16
17      // Użycie this z zakresu zewnętrznego
18      setTimeout(() => {
19        this.status = "Online";
20        this.dinosaurs = [
21          { id: "TRX-01", name: "Rex", species: "Tyrannosaurus", location: "Sektor A", status: "OK" },
22          { id: "VLR-01", name: "Blue", species: "Velociraptor", location: "Sektor B", status: "OK" },
23          { id: "TRC-01", name: "Trixie", species: "Triceratops", location: "Sektor C", status: "OK" }
24        ];
25        this.sectors = ["A", "B", "C", "D"];
26
27        console.log(`System online. Monitorowanych dinozaurów: ${this.dinosaurs.length}`);
28        this.startMonitoring();
29      }, 2000);
30    };
31
32    loadConfigs();
33  },
34
35  // Rozpoczęcie monitoringu
36  startMonitoring() {
37    this.checkSecurity();
38
39    // Sprawdzanie statusu co 5 minut
40    setInterval(() => this.checkStatus(), 300000);
41
42    // Zbieranie danych o dinozaurach co godzinę
43    setInterval(() => this.collectData(), 3600000);
44
45    console.log("Monitorowanie rozpoczęte");
46  },
47
48  // Sprawdzanie statusu dinozaurów
49  checkStatus() {
50    const timestamp = new Date().toISOString();
51
52    // Użycie map z funkcją strzałkową
53    const statusReport = this.dinosaurs.map(dino => ({
54      id: dino.id,
55      name: dino.name,
56      status: dino.status,
57      location: dino.location,
58      timestamp
59    }));
60
61    console.log("Raport statusu dinozaurów:", statusReport);
62    return statusReport;
63  },
64
65  // Sprawdzanie bezpieczeństwa
66  checkSecurity() {
67    console.log("Sprawdzanie stanu bezpieczeństwa parku...");
68
69    // Użycie filter z funkcją strzałkową
70    const compromisedSectors = this.sectors.filter(sector =>
71      Math.random() < 0.1 // 10% szans na problem w każdym sektorze (symulacja)
72    );
73
74    if (compromisedSectors.length > 0) {
75      // Użycie forEach z funkcją strzałkową
76      compromisedSectors.forEach(sector => {
77        const alert = {
78          id: `ALERT-${Date.now()}`,
79          sector,
80          type: "Naruszenie bezpieczeństwa",
81          timestamp: new Date().toISOString()
82        };
83
84        this.securityAlerts.push(alert);
85        this.triggerAlert(alert);
86      });
87    } else {
88      console.log("Wszystkie sektory bezpieczne");
89    }
90  },
91
92  // Wywołanie alertu
93  triggerAlert(alert) {
94    console.log(`ALERT! ${alert.type} w sektorze ${alert.sector}!`);
95
96    // Wywołanie odpowiednich procedur
97    this.notifySecurityTeam(alert);
98  },
99
100  // Powiadomienie zespołu bezpieczeństwa
101  notifySecurityTeam(alert) {
102    const securityPersonnel = ["John Hammond", "Robert Muldoon", "Ray Arnold"];
103
104    // Użycie funkcji strzałkowej do stworzenia wiadomości
105    const createMessage = person => `Powiadamianie ${person} o alercie w sektorze ${alert.sector}`;
106
107    // Wysłanie wiadomości do każdego członka zespołu
108    securityPersonnel.forEach(person => {
109      console.log(createMessage(person));
110    });
111  },
112
113  // Zbieranie danych o dinozaurach
114  collectData() {
115    console.log("Zbieranie danych o dinozaurach...");
116
117    // Użycie reduce z funkcją strzałkową
118    const speciesCount = this.dinosaurs.reduce((counts, dino) => {
119      counts[dino.species] = (counts[dino.species] || 0) + 1;
120      return counts;
121    }, {});
122
123    console.log("Liczba dinozaurów według gatunków:", speciesCount);
124
125    return {
126      timestamp: new Date().toISOString(),
127      totalCount: this.dinosaurs.length,
128      speciesDistribution: speciesCount
129    };
130  }
131};
132
133// Rozpoczęcie działania systemu
134parkMonitoringSystem.initialize();

Podsumowanie

Funkcje strzałkowe wprowadzają kilka istotnych zmian do języka JavaScript:

  1. Bardziej zwięzła składnia - mniej kodu do napisania
  2. Leksykalne wiązanie this - rozwiązuje wiele problemów z kontekstem
  3. Niejawny return - dla funkcji jednolinijkowych

To sprawia, że są one szczególnie przydatne w wielu sytuacjach, takich jak:

  • Funkcje przekazywane do metod tablic (map, filter, reduce)
  • Funkcje zwrotne (callbacks) w timerach, obsłudze zdarzeń
  • Krótkie funkcje pomocnicze

Jednocześnie pamiętajmy o ograniczeniach:

  • Brak własnego this (co jest zaletą lub wadą, w zależności od sytuacji)
  • Brak arguments (choć można użyć parametru rest)
  • Nie można ich używać jako konstruktorów

W naszym Parku Jurajskim, funkcje strzałkowe pomagają nam pisać bardziej zwięzły i przejrzysty kod, co jest niezwykle ważne przy zarządzaniu tak złożonym ekosystemem. W następnych modułach będziemy korzystać z funkcji strzałkowych w różnych kontekstach, co pozwoli nam jeszcze lepiej zrozumieć ich zastosowanie.

Kod do tej lekcji: index.js
1// Funkcje strzałkowe - Park Jurajski
2console.log("Laboratorium Funkcji Strzałkowych");
3console.log("Nowoczesne podejście do funkcji w JavaScript\n");
4
5// ===========================================
6// 1. PODSTAWOWA SKŁADNIA
7// ===========================================
8console.log("=== 1. Składnia funkcji strzałkowych ===");
9
10// Funkcja tradycyjna
11function traditionalRoar(dino) {
12  return `${dino} says: ROAAR!`;
13}
14
15// Funkcja strzałkowa - pełna składnia
16const arrowRoar = (dino) => {
17  return `${dino} says: ROAAR!`;
18};
19
20// Funkcja strzałkowa - skrócona (implicit return)
21const shortRoar = dino => `${dino} says: ROAAR!`;
22
23console.log(traditionalRoar("T-Rex"));
24console.log(arrowRoar("Velociraptor"));
25console.log(shortRoar("Triceratops"));
26
27// ===========================================
28// 2. RÓŻNE WARIANTY SKŁADNI
29// ===========================================
30console.log("\n=== 2. Warianty składni ===");
31
32// Bez parametrów
33const getDinosaurs = () => ["T-Rex", "Velociraptor", "Triceratops"];
34console.log("Lista dinozaurów:", getDinosaurs());
35
36// Jeden parametr (nawiasy opcjonalne)
37const double = x => x * 2;
38console.log("Podwojenie 5:", double(5));
39
40// Wiele parametrów (nawiasy wymagane)
41const calculateWeight = (length, species) => length * (species === "T-Rex" ? 1000 : 500);
42console.log("Waga T-Rexa (12m):", calculateWeight(12, "T-Rex"), "kg");
43
44// Zwracanie obiektu (wymaga nawiasów)
45const createDino = (name, species) => ({
46  name: name,
47  species: species,
48  createdAt: new Date().toISOString()
49});
50
51console.log("\nNowy dinozaur:", createDino("Blue", "Velociraptor"));
52
53// ===========================================
54// 3. PORÓWNANIE Z TRADYCYJNYMI FUNKCJAMI
55// ===========================================
56console.log("\n=== 3. Tradycyjna vs Arrow Function ===");
57
58// Tradycyjna
59function feedTraditional(dino) {
60  console.log(`Karmienie ${dino} (tradycyjna funkcja)`);
61}
62
63// Arrow
64const feedArrow = dino => {
65  console.log(`Karmienie ${dino} (arrow function)`);
66};
67
68feedTraditional("T-Rex");
69feedArrow("Velociraptor");
70
71// ===========================================
72// 4. ARROW FUNCTIONS Z METODAMI TABLICY
73// ===========================================
74console.log("\n=== 4. Arrow functions z metodami tablicy ===");
75
76const dinosaurs = [
77  { name: "Rex", species: "T-Rex", weight: 8000, carnivore: true },
78  { name: "Blue", species: "Velociraptor", weight: 80, carnivore: true },
79  { name: "Trike", species: "Triceratops", weight: 9000, carnivore: false },
80  { name: "Brachio", species: "Brachiosaurus", weight: 50000, carnivore: false }
81];
82
83// map
84const names = dinosaurs.map(dino => dino.name);
85console.log("Imiona:", names);
86
87// filter
88const carnivores = dinosaurs.filter(dino => dino.carnivore);
89console.log("\nMięsożercy:", carnivores.map(d => d.name));
90
91// reduce
92const totalWeight = dinosaurs.reduce((sum, dino) => sum + dino.weight, 0);
93console.log("\nŁączna waga:", totalWeight, "kg");
94
95// forEach
96console.log("\nLista wszystkich dinozaurów:");
97dinosaurs.forEach((dino, index) => {
98  console.log(`  ${index + 1}. ${dino.name} - ${dino.species} (${dino.weight}kg)`);
99});
100
101// find
102const heaviest = dinosaurs.find(dino => dino.weight > 10000);
103console.log("\nNajcięższy (>10000kg):", heaviest ? heaviest.name : "Brak");
104
105// some & every
106const hasHerbivores = dinosaurs.some(dino => !dino.carnivore);
107const allCarnivores = dinosaurs.every(dino => dino.carnivore);
108console.log("\nCzy są roślinożercy?", hasHerbivores);
109console.log("Czy wszyscy są mięsożercami?", allCarnivores);
110
111// ===========================================
112// 5. CHAIN METHODS (ŁAŃCUCHOWANIE)
113// ===========================================
114console.log("\n=== 5. Łańcuchowanie metod ===");
115
116const dangerousHeavyDinos = dinosaurs
117  .filter(dino => dino.carnivore)
118  .filter(dino => dino.weight > 100)
119  .map(dino => `${dino.name} (${dino.weight}kg)`)
120  .sort();
121
122console.log("Niebezpieczne i ciężkie dinozaury:", dangerousHeavyDinos);
123
124// ===========================================
125// 6. CALLBACK FUNCTIONS
126// ===========================================
127console.log("\n=== 6. Arrow functions jako callbacks ===");
128
129function processDinosaurs(dinos, processor) {
130  return dinos.map(processor);
131}
132
133const dinoSummaries = processDinosaurs(dinosaurs, dino =>
134  `${dino.name}: ${dino.carnivore ? 'mięsożerca' : 'roślinożerca'} ${dino.weight}kg`
135);
136
137console.log("Podsumowania:");
138dinoSummaries.forEach(summary => console.log(`  ${summary}`));
139
140// ===========================================
141// 7. ARROW FUNCTIONS W setTimeout/setInterval
142// ===========================================
143console.log("\n=== 7. Arrow functions z timing functions ===");
144
145// setTimeout z arrow function
146setTimeout(() => {
147  console.log("⏰ Czas karmienia! (po 100ms)");
148}, 100);
149
150// Symulacja countdown
151let countdown = 3;
152const countInterval = setInterval(() => {
153  if (countdown > 0) {
154    console.log(`⏳ Odliczanie: ${countdown}...`);
155    countdown--;
156  } else {
157    console.log("Start!");
158    clearInterval(countInterval);
159  }
160}, 50);
161
162// ===========================================
163// 8. RÓŻNICA W ZACHOWANIU 'this'
164// ===========================================
165console.log("\n=== 8. Różnica w kontekście 'this' ===");
166
167const park = {
168  name: "Jurassic Park",
169  dinosaurs: ["T-Rex", "Velociraptor", "Triceratops"],
170
171  // Metoda z tradycyjną funkcją
172  displayTraditional: function() {
173    console.log(`\n${this.name} - Tradycyjna funkcja:`);
174    // this.dinosaurs.forEach(function(dino) {
175    //   // this tutaj NIE odnosi się do park!
176    //   console.log(`  - ${dino}`);
177    // });
178
179    // Rozwiązanie: arrow function w forEach
180    this.dinosaurs.forEach(dino => {
181      console.log(`  - ${dino} z ${this.name}`);
182    });
183  },
184
185  // Metoda z arrow function
186  displayArrow: function() {
187    console.log(`\n${this.name} - Arrow function:`);
188    this.dinosaurs.forEach(dino => {
189      console.log(`  - ${dino} z ${this.name}`);
190    });
191  }
192};
193
194park.displayTraditional();
195park.displayArrow();
196
197// ===========================================
198// 9. KIEDY NIE UŻYWAĆ ARROW FUNCTIONS
199// ===========================================
200console.log("\n=== 9. Kiedy NIE używać arrow functions ===");
201
202// NIE używaj jako metod obiektów (gdy potrzebujesz 'this')
203const dinoObject = {
204  name: "Rex",
205
206  // ZŁE - arrow function jako metoda
207  roarBad: () => {
208    // this nie wskazuje na dinoObject!
209    console.log("this.name:", typeof this.name); // undefined
210  },
211
212  // DOBRE - tradycyjna funkcja jako metoda
213  roarGood: function() {
214    console.log(`${this.name} says: ROAAR!`);
215  }
216};
217
218dinoObject.roarBad();
219dinoObject.roarGood();
220
221// ===========================================
222// 10. PRZYKŁAD KOMPLEKSOWY
223// ===========================================
224console.log("\n=== 10. System monitoringu parku - przykład kompleksowy ===");
225
226const parkSystem = {
227  name: "Isla Nublar",
228  dinosaurs: [
229    { id: 1, name: "Rexy", species: "T-Rex", sector: "A", health: 95, fed: true },
230    { id: 2, name: "Blue", species: "Velociraptor", sector: "B", health: 100, fed: false },
231    { id: 3, name: "Charlie", species: "Velociraptor", sector: "B", health: 88, fed: false },
232    { id: 4, name: "Trike", species: "Triceratops", sector: "C", health: 92, fed: true }
233  ],
234
235  getHealthReport: function() {
236    console.log(`\nRAPORT ZDROWIA - ${this.name}`);
237    console.log("=".repeat(50));
238
239    const avgHealth = this.dinosaurs
240      .map(d => d.health)
241      .reduce((sum, h) => sum + h, 0) / this.dinosaurs.length;
242
243    console.log(`Średnie zdrowie: ${avgHealth.toFixed(1)}%`);
244
245    const needsAttention = this.dinosaurs.filter(d => d.health < 90);
246
247    if (needsAttention.length > 0) {
248      console.log(`\nWymagają uwagi (${needsAttention.length}):`);
249      needsAttention.forEach(d => {
250        console.log(`  - ${d.name}: ${d.health}% zdrowia`);
251      });
252    }
253
254    return { avgHealth, needsAttention: needsAttention.length };
255  },
256
257  getFeedingStatus: function() {
258    console.log(`\nSTATUS KARMIENIA - ${this.name}`);
259    console.log("=".repeat(50));
260
261    const hungryDinos = this.dinosaurs
262      .filter(d => !d.fed)
263      .map(d => ({ name: d.name, sector: d.sector }))
264      .sort((a, b) => a.sector.localeCompare(b.sector));
265
266    if (hungryDinos.length > 0) {
267      console.log(`Głodne dinozaury (${hungryDinos.length}):`);
268      hungryDinos.forEach(d => {
269        console.log(`  Sektor ${d.sector}: ${d.name}`);
270      });
271    } else {
272      console.log("Wszystkie dinozaury nakarmione!");
273    }
274
275    return hungryDinos;
276  },
277
278  getSectorReport: function() {
279    console.log(`\nRAPORT SEKTORÓW - ${this.name}`);
280    console.log("=".repeat(50));
281
282    const sectors = this.dinosaurs.reduce((acc, dino) => {
283      if (!acc[dino.sector]) {
284        acc[dino.sector] = [];
285      }
286      acc[dino.sector].push(dino.name);
287      return acc;
288    }, {});
289
290    Object.entries(sectors)
291      .sort(([a], [b]) => a.localeCompare(b))
292      .forEach(([sector, dinos]) => {
293        console.log(`  Sektor ${sector}: ${dinos.join(", ")}`);
294      });
295
296    return sectors;
297  }
298};
299
300// Uruchom wszystkie raporty
301parkSystem.getHealthReport();
302parkSystem.getFeedingStatus();
303parkSystem.getSectorReport();
304
305console.log("\nGratulacje! Opanowałeś funkcje strzałkowe!");

Widzisz błąd w tej lekcji?

Zadania praktyczne w grze

  • Edytor kodu

    Masz dane: const ageYears = 25, const weightKg = 8000 i const heightM = 5.6. Oblicz ageDays, czyli wiek w dniach (rok ma 365 dni), oraz bmi, czyli wagę podzieloną przez kwadrat wzrostu. Wyświetl w konsoli ageDays i bmi zaokrąglone do dwóch miejsc po przecinku (toFixed(2)).

  • Układanie w poziomie

    Ułóż elementy poprawnej deklaracji zmiennej let z przypisaniem wartości:

  • Edytor kodu

    Masz dane: const fenceVoltage = 10000, const requiredVoltage = 8000, const visitorsInPark = 250 i const maxVisitors = 500. Utwórz zmienne logiczne: isFenceSecure (napięcie jest równe wymaganemu lub większe), isParkFull (liczba gości osiągnęła limit) i canAcceptVisitors (ogrodzenie jest bezpieczne i jednocześnie park nie jest pełny). Wyświetl wszystkie trzy w konsoli.

Przydatne artykuły