Zabawa z podnoszeniem

W dzisiejszej serii TL;DR porozmawiamy o podnoszeniu. Kliknij tutaj, aby dowiedzieć się więcej o serii TL;DR.

W JavaScript wszystkie deklaracje zmiennych używające var są przenoszone na górę zakresu funkcji lub zasięgu globalnego. Oto najważniejsze zasady:

  • Deklaracje funkcji są podnoszone powyżej deklaracji zmiennych.
  • Wyrażenia funkcyjne nie są podnoszone.
  • Przypisania zmiennych nie są podnoszone.
  • Zmienne, którym przypisano wartość przed zadeklarowaniem, automatycznie stają się częścią zasięgu globalnego.
  • Deklaracje są umieszczane na górze bloków funkcyjnych, a nie bloków kodu

Deklaracje funkcji są podnoszone powyżej deklaracji zmiennych.

Po podniesieniu wygląda to następująco:

function foo(){};
var foo;
console.log(typeof foo)

Podnoszenie przenosi deklaracje na górę bloków kodu

Dane wyjściowe są niezdefiniowane! Dzieje się tak, ponieważ var x; w bloku if jest podnoszony na górę funkcji. Przypisanie x=1 jest przechowywane w bloku if, więc x nigdy nie ma przypisanej wartości. Po podniesieniu kod wygląda następująco:

function foo(){
    var x;
    if (false){
        x = 1;
    }
    console.log(x);

Pamiętaj, że przypisanie zmiennej nie jest podnoszone

Po podniesieniu kod jest interpretowany w następujący sposób:

var foo;
function foo(){};
foo = "abc";

Przypisania zmiennych NIE są podnoszone

Po podniesieniu kod jest interpretowany w następujący sposób:

var bar;
console.log(bar);
bar = "abc";
console.log(bar);

Wyrażenia funkcyjne NIE są podnoszone

Uważaj na zasięg globalny

Dlaczego „def”? Zobaczmy najpierw, co się stanie. Deklaracja funkcji bar przenoszona na górę pliku, po której następuje var foo. Wartość foo ma przypisaną wartość „def”, ale po wywołaniu funkcji bar() wartość foo ma przypisaną wartość „def”. Ponieważ foo nie jest deklarowane lokalnie w funkcji bar(), zmienna foo w tym przypadku jest tą samą zmienną foo w zasięgu globalnym. Dlatego w konsoli wypisuje się „def”.

„ściśle dotyczące użytkowania”

Deklaracja „używaj ściśle”; na początku skryptu uniemożliwia przypisanie zmiennych przed deklaracją rozpoczęcia. Używając go, można uniknąć wielu problemów z podnoszeniem.

Z podnoszeniem wiąże się pojęcie zakresu zmiennej JavaScript. Obydwa są ze sobą powiązane i jak mogłeś już zauważyć, nieporozumienie dotyczące podnoszenia i zasięgu może prowadzić do bardzo nieprzyjemnych błędów. Ale to dyskusja na inny dzień!

Chętnie wysłucham wszelkich opinii i informacji, czy jest coś, co przeoczyłem. Zostaw komentarz poniżej!