Kwalifikacja: INF.04 - Projektowanie, programowanie i testowanie aplikacji
Zawód: Technik programista
Co będzie wynikiem działania poniższego kodu JavaScript?
const obj = { name: 'John', greet: function() { setTimeout(function() { console.log(`Hello, ${this.name}`); }, 1000); } }; obj.greet(); |
Odpowiedzi
Informacja zwrotna
Wynik działania tego kodu to `Hello, undefined`, co jest spowodowane tym, jak działa kontekst `this` w JavaScript. Gdy wywołujemy metodę `greet`, w kontekście tej metody `this` odnosi się do obiektu `obj`. Proszę zauważyć, że metoda `greet` używa funkcji anonimowej w `setTimeout`, a to zmienia kontekst `this`. W momencie, gdy `setTimeout` wywołuje funkcję, `this` nie odnosi się już do obiektu `obj`, lecz do globalnego obiektu (w przeglądarkach jest to `window`), gdzie `name` nie jest zdefiniowane. Dlatego w konsoli widzimy `Hello, undefined`. Takie zachowanie jest typowe dla JavaScript, więc warto zrozumieć, jak można to zmienić, np. używając funkcji strzałkowej (`() => {}`), która nie ma własnego kontekstu `this`, więc po prostu korzysta z kontekstu otaczającego. Użycie strzałek w takich przypadkach jest coraz częściej zalecane w nowoczesnym kodzie.
Odpowiedzi `Hello, John`, `TypeError` oraz `Hello, null` są wynikiem niepełnego zrozumienia zasad działania kontekstu `this` w JavaScript oraz mechanizmów związanych z wywołaniami funkcji w różnych kontekstach. W przypadku pierwszej z tych odpowiedzi, można by sądzić, że `this` w funkcji anonimowej odwołuje się do obiektu `obj`, co jest błędne, ponieważ w momencie wywołania funkcji przez `setTimeout` kontekst `this` traci odniesienie do obiektu, a zamiast tego wskazuje na obiekt globalny. W efekcie `this.name` nie zwraca wartości `'John'`, lecz `undefined`. Druga odpowiedź, związana z `TypeError`, nie zrozumiała, że żadne błędy nie są generowane w tym kodzie, a funkcja anonimowa wykonuje się bezproblemowo, jednak z błędnym kontekstem. Ostatnia propozycja, `Hello, null`, również jest nietrafiona, ponieważ nie istnieje sytuacja, w której `this` w tym kontekście mogłoby się odwoływać do `null`. Należy również pamiętać, że JavaScript różni się od wielu innych języków programowania, gdzie `this` jest bardziej ściśle powiązane z obiektem, w którym metoda została wywołana. Zrozumienie kontekstu `this` jest kluczowe w pracy z JavaScript, szczególnie w pracy z funkcjami asynchronicznymi oraz w zastosowaniach programowania obiektowego.