Witaj ponownie w Parku Jurajskim! Dzisiaj zagłębimy się w jedno z najbardziej intrygujących i czasami mylących zagadnień w JavaScript: słowo kluczowe
this. Zrozumienie this jest kluczowe dla efektywnego programowania obiektowego w JavaScript i tworzenia złożonych systemów, takich jak nasz system zarządzania parkiem.Słowo kluczowe
this w JavaScript odnosi się do obiektu, w którego kontekście wykonywana jest funkcja. Można o nim myśleć jak o "aktualnym miejscu pracy" - podobnie jak pracownik Parku Jurajskiego może pracować w różnych lokalizacjach (np. laboratorium, zagroda T-Rexa, centrum kontroli), tak samo funkcja może być wykonywana w różnych kontekstach.Wartość
this nie jest ustalana w momencie definiowania funkcji, ale w momencie jej wywołania, co może powodować pewne zamieszanie. Wartość this zależy od tego, jak funkcja jest wywoływana:call(), apply() lub bind()Przyjrzyjmy się każdemu z tych przypadków.
Gdy
this jest używane w globalnym zasięgu (poza jakąkolwiek funkcją) lub w zwykłej funkcji (niewywołanej jako metoda obiektu), odnosi się do obiektu globalnego. W przeglądarce jest to obiekt window, a w Node.js - global.1// W globalnym zasięgu
2console.log(this); // obiekt window (w przeglądarce) lub global (w Node.js)
3
4// W zwykłej funkcji
5function checkGlobalThis() {
6 console.log(this); // również obiekt window/global
7}
8
9checkGlobalThis();W trybie ścisłym (
"use strict";), this w zwykłej funkcji będzie undefined zamiast obiektu globalnego, co pomaga uniknąć przypadkowego tworzenia globalnych zmiennych.1"use strict";
2
3function strictThis() {
4 console.log(this); // undefined
5}
6
7strictThis();Gdy funkcja jest wywoływana jako metoda obiektu,
this odnosi się do tego obiektu. Jest to jeden z najczęstszych i najbardziej intuicyjnych sposobów użycia this w JavaScript.1// Obiekt reprezentujący dinozaura
2const velociraptor = {
3 name: "Blue",
4 species: "Velociraptor",
5 age: 5,
6
7 // Metoda wykorzystująca this
8 describe: function() {
9 console.log(`Ten ${this.species} ma na imię ${this.name} i ma ${this.age} lat.`);
10 },
11
12 // Metoda zmieniająca dane dinozaura
13 ageDinosaur: function(years) {
14 this.age += years;
15 console.log(`${this.name} ma teraz ${this.age} lat.`);
16 }
17};
18
19// Wywołanie metod
20velociraptor.describe(); // "Ten Velociraptor ma na imię Blue i ma 5 lat."
21velociraptor.ageDinosaur(2); // "Blue ma teraz 7 lat."W powyższym przykładzie,
this wewnątrz metod describe i ageDinosaur odnosi się do obiektu velociraptor, dzięki czemu metody mają dostęp do jego właściwości.Jednak trzeba uważać - kontekst
this może zostać utracony, jeśli metodę przypiszemy do innej zmiennej i wywołamy ją jako zwykłą funkcję:1const velociraptor = {
2 name: "Blue",
3 describe: function() {
4 console.log(`Cześć, jestem ${this.name}!`);
5 }
6};
7
8// Wywołanie jako metoda - this odnosi się do velociraptor
9velociraptor.describe(); // "Cześć, jestem Blue!"
10
11// Ale gdy przypiszemy metodę do zmiennej...
12const describeDino = velociraptor.describe;
13
14// ...i wywołamy jako zwykłą funkcję
15describeDino(); // "Cześć, jestem undefined!"
16// (lub "Cześć, jestem !", jeśli istnieje globalna zmienna name)To częsty problem przy przekazywaniu metod jako funkcji zwrotnych (callbacks):
1const trex = {
2 name: "Rex",
3 roar: function() {
4 console.log(`${this.name} ryczy głośno!`);
5 }
6};
7
8// Bezpośrednie wywołanie działa
9trex.roar(); // "Rex ryczy głośno!"
10
11// Ale jako callback po 1 sekundzie...
12setTimeout(trex.roar, 1000); // "undefined ryczy głośno!"
13
14// Rozwiązanie (jednym ze sposobów) jest użycie funkcji strzałkowej lub bind():
15setTimeout(() => trex.roar(), 1000); // "Rex ryczy głośno!"
16setTimeout(trex.roar.bind(trex), 1000); // "Rex ryczy głośno!"Gdy funkcja jest wywoływana z operatorem
new (jako konstruktor), this odnosi się do nowo tworzonego obiektu. Jest to fundamentalny mechanizm tworzenia instancji obiektów w JavaScript.1// Funkcja konstruktora dla dinozaurów
2function Dinosaur(name, species, age) {
3 // 'this' odnosi się do nowo tworzonego obiektu
4 this.name = name;
5 this.species = species;
6 this.age = age;
7
8 this.describe = function() {
9 console.log(`${this.name} to ${this.species} w wieku ${this.age} lat.`);
10 };
11}
12
13// Tworzenie nowych instancji
14const blue = new Dinosaur("Blue", "Velociraptor", 5);
15const rex = new Dinosaur("Rex", "Tyrannosaurus", 8);
16
17blue.describe(); // "Blue to Velociraptor w wieku 5 lat."
18rex.describe(); // "Rex to Tyrannosaurus w wieku 8 lat."
19
20// Zmodyfikujmy wiek Blue
21blue.age = 6;
22blue.describe(); // "Blue to Velociraptor w wieku 6 lat."W nowoczesnym JavaScript (ES6+) zamiast funkcji konstruktora często używamy klas, które zapewniają bardziej przejrzystą składnię do robienia tego samego:
1// Klasa ES6 dla dinozaurów
2class Dinosaur {
3 constructor(name, species, age) {
4 this.name = name;
5 this.species = species;
6 this.age = age;
7 }
8
9 // Metody są automatycznie dodawane do prototypu
10 describe() {
11 console.log(`${this.name} to ${this.species} w wieku ${this.age} lat.`);
12 }
13
14 // Metoda zmieniająca wiek
15 growOlder(years = 1) {
16 this.age += years;
17 console.log(`${this.name} ma teraz ${this.age} lat.`);
18 }
19}
20
21// Tworzenie instancji
22const trixie = new Dinosaur("Trixie", "Triceratops", 7);
23trixie.describe(); // "Trixie to Triceratops w wieku 7 lat."
24trixie.growOlder(3); // "Trixie ma teraz 10 lat."JavaScript oferuje trzy metody, które pozwalają jawnie kontrolować wartość
this podczas wywoływania funkcji:Metoda
call() wywołuje funkcję z podanym wartością this i argumentami przekazanymi pojedynczo:1function examineSpecimen(testType, labNumber) {
2 console.log(`Badanie ${this.species} o imieniu ${this.name}...`);
3 console.log(`Typ testu: ${testType}, Laboratorium: ${labNumber}`);
4}
5
6const specimen = {
7 name: "Echo",
8 species: "Velociraptor",
9 age: 3
10};
11
12// Wywołanie funkcji z 'this' ustawionym na specimen
13examineSpecimen.call(specimen, "DNA", "Lab-A");
14// "Badanie Velociraptor o imieniu Echo..."
15// "Typ testu: DNA, Laboratorium: Lab-A"Metoda
apply() działa podobnie do call(), ale argumenty są przekazywane jako tablica:1// Ta sama funkcja
2function examineSpecimen(testType, labNumber) {
3 console.log(`Badanie ${this.species} o imieniu ${this.name}...`);
4 console.log(`Typ testu: ${testType}, Laboratorium: ${labNumber}`);
5}
6
7// Wywołanie z argumentami w tablicy
8examineSpecimen.apply(specimen, ["Behawioralny", "Lab-B"]);
9// "Badanie Velociraptor o imieniu Echo..."
10// "Typ testu: Behawioralny, Laboratorium: Lab-B"Metoda
bind() tworzy nową funkcję z trwale przypisaną wartością this:1const dinosaur = {
2 name: "Delta",
3 species: "Velociraptor"
4};
5
6function makeSound(sound) {
7 console.log(`${this.name} wydaje dźwięk: ${sound}!`);
8}
9
10// Tworzenie nowej funkcji z 'this' przypisanym do dinosaur
11const dinosaurSound = makeSound.bind(dinosaur);
12
13// Teraz możemy wywoływać tę funkcję wielokrotnie
14dinosaurSound("Warczenie"); // "Delta wydaje dźwięk: Warczenie!"
15dinosaurSound("Syczenie"); // "Delta wydaje dźwięk: Syczenie!"
16
17// Możemy też powiązać argumenty
18const deltaRoar = makeSound.bind(dinosaur, "ROAR");
19deltaRoar(); // "Delta wydaje dźwięk: ROAR!"Poniższy przykład pokazuje, jak można wykorzystać różne metody kontrolowania
this do tworzenia elastycznego systemu monitorowania:1const dinoMonitoringSystem = {
2 activeDinosaurs: [],
3
4 // Rejestracja nowego dinozaura
5 registerDinosaur: function(dinosaur) {
6 this.activeDinosaurs.push(dinosaur);
7 console.log(`Zarejestrowano nowego dinozaura: ${dinosaur.name} (${dinosaur.species})`);
8 },
9
10 // Wyszukiwanie dinozaura po imieniu
11 findDinosaurByName: function(name) {
12 return this.activeDinosaurs.find(dino => dino.name === name);
13 },
14
15 // Uruchomienie procedury alertu
16 triggerAlert: function(message) {
17 console.log(`ALERT SYSTEMOWY: ${message}`);
18
19 // Powiadamianie o wszystkich aktywnych dinozaurach
20 this.activeDinosaurs.forEach(function(dino) {
21 console.log(`- ${dino.name} (${dino.species}) w sektorze ${dino.sector}`);
22 });
23 }
24};
25
26// Klasa Dinosaur z metodą przemieszczania
27class Dinosaur {
28 constructor(name, species, sector) {
29 this.name = name;
30 this.species = species;
31 this.sector = sector;
32 this.status = "spokojny";
33 }
34
35 move(newSector, monitoringSystem) {
36 // Możemy przekazać monitoringSystem jako parametr
37 console.log(`${this.name} przemieszcza się z sektora ${this.sector} do sektora ${newSector}`);
38 this.sector = newSector;
39
40 // Lub użyć call() do wywołania metody z właściwym kontekstem
41 const alertMessage = `Dinozaur ${this.name} wszedł do sektora ${newSector}!`;
42 monitoringSystem.triggerAlert.call(monitoringSystem, alertMessage);
43 }
44
45 // Metoda zmieniająca status dinozaura
46 updateStatus(newStatus) {
47 this.status = newStatus;
48 console.log(`Status dinozaura ${this.name} zmieniony na: ${this.status}`);
49 return this;
50 }
51}
52
53// Inicjalizacja systemu i dinozaurów
54const rex = new Dinosaur("Rex", "Tyrannosaurus", "A");
55const blue = new Dinosaur("Blue", "Velociraptor", "B");
56const delta = new Dinosaur("Delta", "Velociraptor", "B");
57
58// Rejestracja dinozaurów w systemie
59dinoMonitoringSystem.registerDinosaur(rex);
60dinoMonitoringSystem.registerDinosaur(blue);
61dinoMonitoringSystem.registerDinosaur(delta);
62
63// Przemieszczenie dinozaura
64blue.move("C", dinoMonitoringSystem);
65
66// Łańcuchowanie metod (dzięki return this)
67rex.updateStatus("pobudzony").updateStatus("agresywny");
68
69// Wykorzystanie bind() do tworzenia funkcji z predefiniowanym 'this'
70const checkRexStatus = function() {
71 console.log(`Status T-Rexa: ${this.status}`);
72};
73
74const boundCheckStatus = checkRexStatus.bind(rex);
75boundCheckStatus(); // "Status T-Rexa: agresywny"Funkcje strzałkowe, wprowadzone w ES6, obsługują
this inaczej niż tradycyjne funkcje. Nie mają własnego this, zamiast tego "dziedziczą" this z otaczającego zakresu leksykalnego.1const parkSystem = {
2 name: "Jurassic Park",
3 dinosaurs: ["T-Rex", "Velociraptor", "Triceratops"],
4
5 // Metoda wykorzystująca funkcję strzałkową
6 listDinosaurs: function() {
7 console.log(`${this.name} zawiera następujące dinozaury:`);
8
9 // Funkcja strzałkowa zachowuje 'this' z zakresu listDinosaurs
10 this.dinosaurs.forEach(dino => {
11 console.log(`- ${dino} w parku ${this.name}`);
12 });
13
14 // Dla porównania - tradycyjna funkcja straciłaby kontekst 'this'
15 /*
16 this.dinosaurs.forEach(function(dino) {
17 // 'this' odnosi się do globalnego obiektu lub jest undefined w trybie ścisłym
18 console.log(`- ${dino} w parku ${this.name}`); // this.name będzie undefined
19 });
20 */
21 }
22};
23
24parkSystem.listDinosaurs();
25// "Jurassic Park zawiera następujące dinozaury:"
26// "- T-Rex w parku Jurassic Park"
27// "- Velociraptor w parku Jurassic Park"
28// "- Triceratops w parku Jurassic Park"Funkcje strzałkowe są szczególnie przydatne w przypadkach, gdy chcemy zachować kontekst
this w funkcjach zagnieżdżonych, funkcjach zwrotnych (callbacks) lub programowaniu asynchronicznym.1class DinosaurMonitor {
2 constructor(name, species) {
3 this.name = name;
4 this.species = species;
5 this.status = "Normalny";
6 this.lastUpdated = new Date();
7 this.checkInterval = null;
8 }
9
10 // Rozpoczęcie monitorowania z regularnym sprawdzaniem statusu
11 startMonitoring() {
12 console.log(`Rozpoczęcie monitorowania dinozaura: ${this.name}`);
13
14 // Funkcja strzałkowa zachowuje kontekst 'this'
15 this.checkInterval = setInterval(() => {
16 this.checkStatus();
17 }, 5000);
18
19 // Gdybyśmy użyli zwykłej funkcji, stracilibyśmy kontekst:
20 /*
21 this.checkInterval = setInterval(function() {
22 // 'this' odnosi się tutaj do globalnego obiektu, nie do instancji DinosaurMonitor
23 this.checkStatus(); // Błąd: this.checkStatus is not a function
24 }, 5000);
25 */
26 }
27
28 // Sprawdzenie statusu dinozaura
29 checkStatus() {
30 const now = new Date();
31 const timeSinceLastUpdate = (now - this.lastUpdated) / 1000; // w sekundach
32
33 console.log(`Sprawdzanie statusu dinozaura ${this.name} (${this.species})...`);
34 console.log(`Ostatnia aktualizacja: ${timeSinceLastUpdate.toFixed(1)} sekund temu`);
35 console.log(`Status: ${this.status}`);
36
37 this.lastUpdated = now;
38
39 // Symulacja zmiany statusu (w rzeczywistym systemie byłyby tu dane z czujników)
40 if (Math.random() < 0.3) {
41 const possibleStatuses = ["Normalny", "Pobudzony", "Odpoczywający", "Żerujący", "Agresywny"];
42 this.status = possibleStatuses[Math.floor(Math.random() * possibleStatuses.length)];
43 console.log(`Nowy status: ${this.status}`);
44 }
45 }
46
47 // Zatrzymanie monitorowania
48 stopMonitoring() {
49 if (this.checkInterval) {
50 clearInterval(this.checkInterval);
51 this.checkInterval = null;
52 console.log(`Zatrzymano monitorowanie dinozaura: ${this.name}`);
53 }
54 }
55}
56
57// Utworzenie i uruchomienie monitora
58const blueMonitor = new DinosaurMonitor("Blue", "Velociraptor");
59blueMonitor.startMonitoring();
60
61// Zatrzymanie monitora po 20 sekundach
62setTimeout(() => {
63 blueMonitor.stopMonitoring();
64}, 20000);Słowo kluczowe
this może być źródłem wielu błędów w JavaScript. Oto kilka typowych pułapek i jak ich unikać:1const dinosaur = {
2 name: "Rex",
3 behaviors: ["polowanie", "odpoczynek", "bieganie"],
4
5 logBehaviors: function() {
6 // 'this' odnosi się tutaj do 'dinosaur'
7 console.log(`Dinozaur ${this.name} wykazuje następujące zachowania:`);
8
9 // Problem: 'this' w funkcji forEach odnosi się do globalnego obiektu
10 this.behaviors.forEach(function(behavior) {
11 // 'this.name' jest undefined
12 console.log(`- ${this.name} lubi ${behavior}`);
13 });
14 }
15};
16
17dinosaur.logBehaviors();
18// "Dinozaur Rex wykazuje następujące zachowania:"
19// "- undefined lubi polowanie"
20// "- undefined lubi odpoczynek"
21// "- undefined lubi bieganie"Rozwiązania:
1const dinosaur = {
2 name: "Rex",
3 behaviors: ["polowanie", "odpoczynek", "bieganie"],
4
5 logBehaviors: function() {
6 console.log(`Dinozaur ${this.name} wykazuje następujące zachowania:`);
7
8 // Funkcja strzałkowa zachowuje 'this' z otaczającego zakresu
9 this.behaviors.forEach(behavior => {
10 console.log(`- ${this.name} lubi ${behavior}`);
11 });
12 }
13};this w zmiennej:1const dinosaur = {
2 name: "Rex",
3 behaviors: ["polowanie", "odpoczynek", "bieganie"],
4
5 logBehaviors: function() {
6 console.log(`Dinozaur ${this.name} wykazuje następujące zachowania:`);
7
8 // Zachowanie referencji do 'this' w zmiennej 'self' lub 'that'
9 const self = this;
10 this.behaviors.forEach(function(behavior) {
11 console.log(`- ${self.name} lubi ${behavior}`);
12 });
13 }
14};bind():1const dinosaur = {
2 name: "Rex",
3 behaviors: ["polowanie", "odpoczynek", "bieganie"],
4
5 logBehaviors: function() {
6 console.log(`Dinozaur ${this.name} wykazuje następujące zachowania:`);
7
8 // Użycie bind() do powiązania 'this'
9 this.behaviors.forEach(function(behavior) {
10 console.log(`- ${this.name} lubi ${behavior}`);
11 }.bind(this));
12 }
13};Gdy metoda obiektu jest przekazywana jako callback, traci swój kontekst
this:1class DinosaurTracker {
2 constructor(name) {
3 this.name = name;
4 this.tracked = false;
5 }
6
7 startTracking() {
8 this.tracked = true;
9 console.log(`Rozpoczęto śledzenie dinozaura ${this.name}`);
10 }
11}
12
13const blueTracker = new DinosaurTracker("Blue");
14
15// Działa poprawnie
16blueTracker.startTracking();
17
18// Nie działa - 'this' nie odnosi się do blueTracker
19setTimeout(blueTracker.startTracking, 1000); // "Rozpoczęto śledzenie dinozaura undefined"Rozwiązania:
1setTimeout(() => blueTracker.startTracking(), 1000);bind():1setTimeout(blueTracker.startTracking.bind(blueTracker), 1000);Poniżej znajduje się bardziej złożony przykład systemu zarządzania Parkiem Jurajskim, który wykorzystuje różne aspekty słowa kluczowego
this:1// Główny system zarządzania parkiem
2const parkManagementSystem = {
3 parkName: "Jurassic Park",
4 status: "operational",
5 securityLevel: "normal",
6
7 // Podsystemy parku
8 subsystems: {
9 power: { status: "online", output: "100%" },
10 security: { status: "active", fences: "operational" },
11 visitorCenter: { status: "open", visitors: 120 }
12 },
13
14 // Metoda inicjująca system
15 initialize: function() {
16 console.log(`Inicjalizacja systemu zarządzania parkiem: ${this.parkName}`);
17
18 // Sprawdzenie wszystkich podsystemów
19 this.checkAllSubsystems();
20
21 // Ustawienie regularnego monitorowania
22 this.startMonitoring();
23
24 return this;
25 },
26
27 // Sprawdzenie stanu podsystemów
28 checkAllSubsystems: function() {
29 console.log("Sprawdzanie statusu wszystkich podsystemów...");
30
31 // Użycie Object.entries i funkcji strzałkowej dla zachowania kontekstu 'this'
32 Object.entries(this.subsystems).forEach(([name, system]) => {
33 console.log(`- Podsystem ${name}: ${system.status}`);
34
35 // Wywołanie specyficznych sprawdzeń dla każdego podsystemu
36 this[`check${name.charAt(0).toUpperCase() + name.slice(1)}`]();
37 });
38 },
39
40 // Specyficzne metody sprawdzające dla każdego podsystemu
41 checkPower: function() {
42 const powerSystem = this.subsystems.power;
43 console.log(` Sprawdzanie zasilania: ${powerSystem.status}, Moc: ${powerSystem.output}`);
44 },
45
46 checkSecurity: function() {
47 const securitySystem = this.subsystems.security;
48 console.log(` Sprawdzanie zabezpieczeń: ${securitySystem.status}, Ogrodzenia: ${securitySystem.fences}`);
49 },
50
51 checkVisitorCenter: function() {
52 const visitorSystem = this.subsystems.visitorCenter;
53 console.log(` Sprawdzanie centrum dla zwiedzających: ${visitorSystem.status}, Odwiedzający: ${visitorSystem.visitors}`);
54 },
55
56 // Rozpoczęcie regularnego monitorowania
57 startMonitoring: function() {
58 console.log("Rozpoczęcie regularnego monitorowania parku...");
59
60 // Funkcja strzałkowa dla zachowania kontekstu 'this'
61 this.monitoringInterval = setInterval(() => {
62 this.checkSecurityStatus();
63 }, 10000);
64
65 // Symulacja wywołania metody po 5 sekundach
66 setTimeout(() => this.simulateSecurityAlert(), 5000);
67 },
68
69 // Sprawdzenie statusu bezpieczeństwa
70 checkSecurityStatus: function() {
71 console.log(`[MONITOR] Status parku: ${this.status}, Poziom bezpieczeństwa: ${this.securityLevel}`);
72 },
73
74 // Symulacja alertu bezpieczeństwa
75 simulateSecurityAlert: function() {
76 console.log("SYMULACJA: Wykryto naruszenie zabezpieczeń w sektorze B!");
77
78 // Zmiana statusu parku i poziomu bezpieczeństwa
79 this.status = "alert";
80 this.securityLevel = "high";
81 console.log(`Status parku zmieniony na: ${this.status}`);
82 console.log(`Poziom bezpieczeństwa podniesiony do: ${this.securityLevel}`);
83
84 // Bezpośrednie sprawdzenie statusu
85 this.checkSecurityStatus();
86
87 // Utworzenie zespołu reagowania kryzysowego używając konstruktora
88 const responseTeam = new EmergencyResponseTeam(this);
89
90 // Przekazanie metody jako callback z zachowaniem kontekstu
91 responseTeam.respondToAlert(this.resolveSecurityAlert.bind(this));
92 },
93
94 // Rozwiązanie alertu bezpieczeństwa
95 resolveSecurityAlert: function(report) {
96 console.log(`Otrzymano raport od zespołu reagowania: ${report}`);
97
98 // Przywrócenie normalnego statusu
99 this.status = "operational";
100 this.securityLevel = "normal";
101 console.log("Alert bezpieczeństwa rozwiązany.");
102 console.log(`Status parku przywrócony do: ${this.status}`);
103
104 // Sprawdzenie aktualnego statusu
105 this.checkSecurityStatus();
106 },
107
108 // Zatrzymanie monitorowania
109 stopMonitoring: function() {
110 if (this.monitoringInterval) {
111 clearInterval(this.monitoringInterval);
112 console.log("Monitorowanie parku zatrzymane.");
113 }
114 }
115};
116
117// Konstruktor dla zespołu reagowania kryzysowego
118function EmergencyResponseTeam(park) {
119 // 'this' odnosi się do nowego obiektu
120 this.teamName = "Zespół Reagowania Kryzysowego";
121 this.members = ["Owen Grady", "Claire Dearing", "Dr. Wu"];
122 this.assignedPark = park;
123
124 this.respondToAlert = function(callback) {
125 console.log(`${this.teamName} reaguje na alert w parku: ${this.assignedPark.parkName}`);
126
127 // Symulacja czasu reakcji
128 setTimeout(() => {
129 console.log(`${this.teamName} zabezpieczył obszar i przywrócił ogrodzenia.`);
130
131 // Wywołanie callbacka z raportem
132 if (typeof callback === 'function') {
133 callback("Zagrożenie zneutralizowane, ogrodzenia naprawione");
134 }
135 }, 3000);
136 };
137}
138
139// Inicjalizacja i uruchomienie systemu
140parkManagementSystem.initialize();
141
142// Zatrzymanie systemu po 20 sekundach
143setTimeout(() => {
144 parkManagementSystem.stopMonitoring();
145}, 20000);Słowo kluczowe
this jest potężnym narzędziem w JavaScript, ale wymaga zrozumienia, jak się zachowuje w różnych kontekstach:W globalnym kontekście:
this odnosi się do obiektu globalnego (window lub global).W metodzie obiektu:
this odnosi się do obiektu, który wywołał metodę.W konstruktorze:
this odnosi się do nowo tworzonego obiektu.W funkcjach strzałkowych:
this jest dziedziczone z otaczającego zakresu leksykalnego.Przy użyciu call/apply/bind:
this jest jawnie określone przez programistę.Używaj funkcji strzałkowych dla funkcji zwrotnych (callbacks) i funkcji zagnieżdżonych, aby zachować kontekst
this.Używaj metod
, call()
lub apply()
, gdy potrzebujesz jawnie kontrolować wartość bind()
this.Unikaj tworzenia metod w konstruktorach, zamiast tego dodawaj je do prototypu, aby uniknąć duplikacji kodu.
Pamiętaj, że
jest ustalane podczas wywoływania funkcji, a nie podczas jej definiowania.this
Używaj klas ES6 zamiast tradycyjnych konstruktorów, aby uzyskać bardziej przejrzysty kod.
W następnym module zajmiemy się głębiej tablicami w JavaScript, które są kluczowym elementem zarządzania kolekcjami danych w naszym Parku Jurajskim.