Hoisting to kolejny z podstawowych terminów w JavaScript. Znajomość tego zagadnienia często wymagana jest procesu rekrutacyjnego i pomaga w zrozumieniu działania kodu JavaScript.
Czym jest hoisting?
Hoisting (windowanie) mówi o tym jak działa JavaScript. W języku JavaScript podczas wykonywania kodu wszystkie deklaracje zmiennych oraz funkcji „przenoszone są na początek”, co oznacza że nieważna jest kolejność deklaracji i wywołania. Najpierw możemy wywołać funkcję, a dopiero potem ją zdefiniować.
„Przenoszone” – oczywiście tego nie powinniśmy rozumieć dosłownie. JavaScript najpierw wyszukuje w kodzie wszystkie deklaracje zmiennych i funkcji, a następnie zapisuje je w pamięci. Dopiero potem wykonuje kod.
Przykład hoistingu z funkcją
sum(2,2); // 4
function sum(a, b) {
return a+b;
}
W powyższym przykładzie najpierw wywołałem funkcję sum(), a potem ją zadeklarowałem. Funkcja wykona się i zwróci 4. To jest właśnie przykład hoistingu.
Przykład hoistingu ze zmienną var
a = 10;
var a;
W przykładzie ze zmienną var najpierw wykonuję przypisanie wartości do zmiennej, a następnie ją deklaruję. Powyższy kod zgodnie z działaniem JavaScriptu można rozumieć w ten sposób:
var a;
a = 10;
To jest przykład hoistingu z wykorzystaniem zmiennych.
Hoisting i wyrażenie funkcyjne (function expression)
Wyrażenie funkcyjne nie będą hoistowane, ponieważ to nie jest deklaracja funkcji.
test(); // TypeError: test is not a function
var test = function() {
return 'hurra!';
}
Powyższy przykład zwróci błąd. Hoistowanie dotyczy tylko deklaracji, czyli przypisanie zmiennej do funkcji (function expression) nie zostanie „przeniesione” na górę.
Hoisting z let, const
Deklaracja let
W przypadku let trzeba spodziewać się trochę innego działania, niż var.
a = 10; // ReferenceError: can't access lexical declaration `a' before initialization
let a;
W powyższym przykładzie otrzymaliśmy błąd, który mówi że nie ma dostępu do zmiennej a przed inicjalizacją. Inicjalizacja zmiennej let następuje w momencie przypisania do niej wartości. Dopóki nie nastąpi inicjalizacja, nie można wykorzystywać zmiennej let.
Czy hoisting z let tutaj zachodzi? Tak, tylko początkową wartością jest uninitialized.
function test() {
console.log(a);
}
let a = 10;
test();
Powyższy kod zadziała poprawnie. Najpierw deklaruję funkcję test(), a następnie zmienną a. W momencie wykonywania funkcji test(), zmienna a jest już „zainicjalizowana„.
Deklaracja const
W przypadku const sprawa jest bardzo podobna do let. Dopóki zmienna nie zostanie „zainicjalizowana” wartością, będzie miała wartość uninitialized.
a = 10; // SyntaxError: missing = in const declaration
const a;
Różnica jest w zwracanym błędzie.
Deklaracja class
class również jest hoistowane i działa podobnie do let i const.
let testVar = new Test('value');
console.log(testVar); // ReferenceError: can't access lexical declaration `Test' before initialization
class Test {
constructor(example) {
this.example = example
}
}
Podsumowanie
Teraz już wiadomo na czym polega hoisting w JavaScript. Zrozumienie tego zagadnienia z pewnością pozwoli uniknąć popełnienia kilku prostych błedów. Dla osób bardziej ciekawskich poniżej źródła informacji, gdzie można uzupełnić wiedzę.
Materiały
Advanced Javascript – Kyle Simpson (płatne) – https://www.pluralsight.com/courses/advanced-javascript
Hoisting na MDN – https://developer.mozilla.org/pl/docs/Glossary/Hoisting
Hoisting in Modern JavaScript — let, const, and var – https://blog.bitsrc.io/hoisting-in-modern-javascript-let-const-and-var-b290405adfda
Dodaj komentarz