Kurs JavaScript i TypeScript · Moduł 2: Funkcje, tablice i obiekty
Funkcje strzałkowe (arrow functions)
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:
- Nie używa słowa kluczowego
function - 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:
- Bardziej zwięzła składnia - mniej kodu do napisania
- Leksykalne wiązanie
this- rozwiązuje wiele problemów z kontekstem - 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.