Funkcije u Javaskripti

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

Ovo je neka vrsta kombinovanog stila izrazne deklaracije i funkcijske deklaracije!
var fun = function staro(){
	alert("Izrazna deklaracija");
}
Preporučujem korišćenje ovog tipa pre nego anonimnog, zato što u slučaju debagovanja u pregledaču, videćete privremeno ime funkcije, dok će kod anonimne biti `anonymous function`.
Oblas važenja:
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.