De ce pot folosi o funcție înainte să fie definită în JavaScript?
Acest cod funcționează întotdeauna, chiar și în diferite browsere:
function fooCheck() {
alert(internalFoo()); // We are using internalFoo() here...
return internalFoo(); // And here, even though it has not been defined...
function internalFoo() { return true; } //...until here!
}
fooCheck();
Totuși, nu am putut găsi nicio referință despre motivul pentru care ar trebui să funcționeze. Am văzut asta pentru prima dată în notițele de prezentare ale lui John Resig, dar a fost doar menționat. Nu există nicio explicație acolo sau nicăieri, de altfel.
Ar putea cineva să mă lămurească, vă rog?
Răspuns #1
Declarația function este magică și face ca identificatorul să fie legat înainte ca orice din blocul său de cod* să fie executat.
Acest lucru diferă de o atribuire cu o expresie function, care este evaluată în ordinea normală de sus în jos.
Dacă ai schimba exemplul să spună:
var internalFoo = function() { return true; };
ar înceta să funcționeze.
Declarația funcției este sintactic destul de separată de expresia funcției, chiar dacă arată aproape identic și poate fi ambiguă în unele cazuri.
Acest lucru este documentat în standardul ECMAScript, secțiunea 10.1.3. Din păcate, ECMA-262 nu este un document foarte ușor de citit chiar și după standardele documentelor standard!
*: funcția, blocul, modulul sau scriptul care îl conține.
Răspunsul #2
Se numește HOISTING - Invocarea (apelarea) unei funcții înainte ca aceasta să fie definită.
Două tipuri diferite de funcții despre care vreau să scriu sunt:
Funcții de expresie și funcții declarative
Funcții de expresie:
Expresiile de funcție pot fi stocate într-o variabilă, astfel încât să nu necesite nume de funcție. Ele vor fi, de asemenea, numite funcție anonimă (o funcție fără nume).
Pentru a invoca (apela) aceste funcții, ele au nevoie întotdeauna de un nume de variabilă. Acest tip de funcție nu va funcționa dacă este apelată înainte de a fi definită, ceea ce înseamnă că Hoisting-ul nu are loc aici. Trebuie să definim întotdeauna mai întâi funcția expresie și apoi să o invocăm.
let lastName = function (family) { console.log("My last name is " + family); }; let x = lastName("Lopez");Așa poți să-l scrii în ECMAScript 6:
lastName = (family) => console.log("My last name is " + family); x = lastName("Lopez");Funcții de declarație:
Funcțiile declarate cu următoarea sintaxă nu sunt executate imediat. Ele sunt „salvate pentru utilizare ulterioară” și vor fi executate mai târziu, când sunt invocate (apelate). Acest tip de funcție funcționează dacă o apelezi ÎNAINTE sau DUPĂ locul unde a fost definită. Dacă apelezi o funcție declarată înainte de a fi definită, Hoisting-ul funcționează corect.
function Name(name) { console.log("My cat's name is " + name); } Name("Chloe");Exemplu de ridicare:
Name("Chloe"); function Name(name) { console.log("My cat's name is " + name); }
Răspunsul #3
Browserul citește HTML-ul tău de la început până la sfârșit și îl poate executa pe măsură ce este citit și analizat în bucăți executabile (declarații de variabile, definiții de funcții, etc.). Dar, în orice moment, poate folosi doar ceea ce a fost definit în script înainte de acel punct.
Acesta este diferit de alte contexte de programare care procesează (compilează) tot codul sursă, eventual îl leagă cu toate bibliotecile de care aveți nevoie pentru a rezolva referințele și construiesc un modul executabil, moment în care începe execuția.
Codul tău poate face referire la obiecte denumite (variabile, alte funcții etc.) care sunt definite mai târziu, dar nu poți executa codul care face referire până când toate componentele nu sunt disponibile.
Pe măsură ce te familiarizezi cu JavaScript, vei deveni profund conștient de necesitatea de a scrie lucrurile în ordinea corectă.
Revizuire: Pentru a confirma răspunsul acceptat (de mai sus), folosiți Firebug pentru a parcurge secțiunea de script a unei pagini web. Veți vedea că trece de la o funcție la alta, vizitând doar prima linie, înainte de a executa efectiv orice cod.
