U većini programskih jezika smo navikli da se funkcije pišu pisanjem neke ključne reči (najčešće function
) zatim ime funkcije i zagrade u kojima se definisu parametri funkcije.
U javaskripti je to jedan ali ne i jedini način za definisanje funkcije i često kod novih korisnika se stvara neka vrsta konfuzije. Koji je način bolji, koje su razlike?
Postoje dve vrste deklaracije:
- Funcijska deklaracija (standardna)
- Izrazna deklaracija
Funcijska deklaracija
Ovo je standardna deklaracija, na koju smo navikli kao u većini jezika, koristi se ključna reč function
, zatim ime funkcije i zagrade za listu parametra.
function fun() {
alert('Ja sam funkcijaa!');
}
Izrazne deklaracije
Ova vrsta deklaracije je nešto sa čime se verovatno niste susreli. Funkcija se definise u vidu promenjive.
Postoje dve podvrste:
- Anonimne izrazne deklaracije
- Imenovane izrazne deklaracije
Anonimne
Anonimna funkcija je ona koja nema naziv.
U primeru ćemo promenjivoj fun
"dodeliti" anonimnu funkciju, koja tada dobije ime fun
.
var fun = function(){
alert("Izrazna deklaracija");
};
Funkcija se poziva normalno kao i pre fun()
.
Imenovane
Imenovane funkcije su, kada funkcijski delkarisanu funkciju upišemo u promenjivu. Tako smo joj ujedno promenili ime a i stil, sada je izrazno deklarisana funkcija
var fun = function staro(){
alert("Izrazna deklaracija");
}
Ovde je interesantno napomenuti koja je oblast veženja.
Stara funkcija je privremena funkcija koju možemo koristi SAMO unutar deklaracije, što nam omogućava da globalno ime funkcije bude jedno, a unutar funkcije bude neko drugo ime.
var puno-ime-funkcije = function kratko(i) {
// Iskoristimo kraće ime za rekurziju
kratko(i + 10);
};
Ovo funkcioniše baš kako treba, zato što kratko
je privremena funkcija koja se kreira, i okvir važenja njenog imena je unutar svog tela.
Kao što sam ponovio već par puta, kratko
je privremena funkcija, tako da ne važi van svog okvira.
puno-ime-funkcije(10); // funkcioniše bez problema
kratko(10) // undefined - zato što ta funkcija ne postoji
Razlika
Pre nego što ih uporedimo moramo da se upoznamo sa terminom podizanje (engl: hoisting) u javaskripti.
Podizanje u javaskripti je usađeno ponašanje u javaskripti koje pomera sve deklaracije na početku trenutnog okvira (scope-a).
Vodeći se ovim gore, ovaj primer je validan u javaskripti.
x = "Hahaha ovo radi";
alert(x); // Izbacice alert sa tekstom "Hahaha ovo radi"
var x;
Ovo radi bez problema zato što interpretator javaskripte gleda unapred i sve deklaracije pomera na vrh okvira. Tako je naša deklaracija x
prešla na vrh.
Ovo se sve dešava u nekom pretprocesu!
Ovo važi i za funkcijske deklaracije!
fun(); // Ovo bez ikakvih problema poziva funkciju fun
function fun() {
alert('Ja sam funkcijaa!');
}
Ovo je sve posledica podizanja u javaskripti, koje deklaracije podiže na vrh okvira.
Ovo ne važi za izrazne deklaracije
fun(); // undefined
var fun = function(){}; // definicija funkcije, važi na dole
fun(); // Radi bez problema
Ovo je glavna razika između ovih deklaracija. Ukratko:
Funkcijska deklaracija je globalna i može se pozvati pre i posle same deklaracije, dok izrazna deklaracija važi samo posle same deklaracije.
Šta je bolje?
Na ovo pitanje ću odogoriti subjektivno i podeliti svoje mišljenje.
Izrazna deklaracija je po mom mišljenju bolja zato što mogu da kontrolišem oblast delovanja te funkcije. Generalni savet u programiranju je da treba
izbegavati nedefinisana ponašanja (silent radnje kompajlera, interpretatora), ne treba se oslanjati da kompjuter radi vaš posao zato što on ne zna šta vi hoćete.