Kurs obiektowego JavaScript (13)

Autor: Damian Chodorek • Opublikowany: 29 września 2014 • Ostatnia aktualizacja: 8 lutego 2015 • Kategoria: javascript, kursy

Wywołanie funkcji przy definicji, zagnieżdżanie, zwracanie i nadpisywanie funkcji.

Do tej pory poznałeś wykorzystanie funkcji anonimowych jako callbacków. Mają one jeszcze inne zastosowanie. Funkcje anonimowe można wywołać zaraz po ich zdefiniowaniu. Jak to zrobić, skoro nie mają nazwy?

(
  function(){
    alert("!");
  }
)()

Konstrukcja może wyglądać dziwnie na początku, ale w rzeczywistości jest bardzo prosta. Umieszczamy naszą funkcję wewnątrz nawiasów i na końcu dajemy jeszcze jeden zestaw nawiasów. Drugie nawiasy odpowiadają za wykonanie funkcji oraz są miejscem wpisania ewentualnych parametrów jeśli funkcja ich potrzebuje.

(
  function(imie){
    alert("Witaj "+imie);
  }
)("Jan")

Tego rodzaju funkcje przydają się, gdy trzeba zrobić coś raz, bez tworzenia zmiennej globalnej.

Funkcje zagnieżdżone (prywatne)

Skoro funkcje są w JS jak dane, nic nie stoi na przeszkodzie, aby zdefiniować jedną wewnątrz drugiej.

function f1(param1){
  function f2(param2){
    return param2*2;
  };

  return "Wynik to "+f2(param1);
}

Wywołanie funkcji f1() spowoduje, iż wywoła ona f2(). Skoro ta druga została zdefiniowana wewnątrz f1(), to jest lokalna, a więc widoczna wyłącznie w f1(). Nic nie stoi na przeszkodzie, aby zdefiniować ją jak poniżej.

function f1(param1){
  var f2=function(param2){
    return param2*2;
  };

  return "Wynik to "+f2(param1);
}

f1(3); //6
f2(3); //BŁĄD, f2 jest niewidoczna poza f1

Zalety i konsekwencje funkcji prywatnych są ogromne:

  • są mniejsze szanse, że ktoś stworzy funkcje o tej samej nazwie co Ty,
  • udostępniasz na zewnątrz wyłącznie te funkcje, które chcesz, a całą resztę trzymasz ukrytą.

Skoro funkcja może zwrócić dowolną wartość, to nic nie przeszkadza, aby była to inna funkcja.

function f1(){
  alert("f1()");
  return function(){
    alert("f2()");
  };
}

var nowa=f1(); //wyświetli komunikat "f1" i zwróci funkcję
nowa(); //wyświetli komunikat "f2"

f1()(); /*a to zapis bez przypisania funkcji zwracanej do zmiennej, funkcja zwracana zostanie od razu wywołana*/

Funkcje nadpisujące się

Funkcję zwracaną jako wartość można przypisać do funkcji, która ją zwraca.

f1=f1();

Teraz przy pierwszym wywołaniu f1() wyświetli komunikat "f1()", a przy drugim "f2()". Jest to przydatne kiedy chcemy, aby przy pierwszym wywołaniu funkcja wykonywała jakieś czynności inicjalizacyjne, a przy kolejnych normalną pracę, bez niepotrzebnego powtarzania czynności.

W ostatnim przykładzie funkcja f1() została nadpisana poza swoją definicją, ale równie dobrze można tego dokonać w niej samej.

function f1(){
  alert("f1()");
  f1=function(){
    alert("f2()");
  };
}

Pierwsze wywołanie funkcji spowoduje wyświetlenie komunikatu "f1()" oraz przypisanie do zmiennej globalnej f1 (która reprezentuje wywoływaną funkcję) innej funkcji. Kolejne wywołania spowodują wyświetlenie komunikatu "f2()".

Poniżej przykład, który jest podsumowaniem poznanych informacji.

var a=function(){
  
  function ini(){
    alert("inicjalizacja");
  }

  function zadanie(){
    alert("praca...");
  }  

  ini();
  return zadanie;
}()

Co się dzieje w powyższym przykładzie?

  1. W funkcji a() zdefiniowano dwie funkcje prywatne: ini() oraz zadanie().
  2. Nawiasy na końcu gwarantują, że funkcja a() wykona się od razu po zdefiniowaniu.
  3. Wywołanie a() spowoduje wywołanie ini() oraz zwrócenie referencji do funkcji zadanie(), która zostanie przypisana zmiennej a.

Zachęcam do wykonania powyższego kodu i zrozumienia co się stanie.

W tym artykule to wszystko. Przejdź do następnej części:

Kurs obiektowego JavaScript (14)

Zobacz również
Kurs obiektowego JavaScript (11)Zmienne globalne. Nietypowy zakres zmiennych lokalnych.
Kurs obiektowego JavaScript (12)Przedstawienie funkcji anonimowych i zwrotnych (callback).
Kurs obiektowego JavaScript (14)Łańcuch zasięgu i jego przerywanie. Gettery, settery.
Kurs obiektowego JavaScript (15)Wstęp do obiektów. Omówienie pól i metod. Konstruktory i słowo kluczowe new.

5 komentarzy

  • alek napisał(a):

    Kurs jest dość szczegółowy ale niektóre opisy nie pasują do listingów kodu.

  • fauxliver napisał(a):

    Super kurs. Ale zaciąłem się w tym punkcie przy przypisaniu funkcji do zmiennej globalnej:
    var nowa=f1();
    nowa();
    dlaczego właściwie przy przypisaniu nie zadziała całe ciało funkcji tylko część alert f1 i return?

    jak usunę nowa(); – to wtedy nic się nie zadzieje – nie umiem za bardzo dojrzeć połączenia.

    • Damian Chodorek napisał(a):

      Cześć. Dobre pytanie. Funkcje w JS to również dane – podobnie jak np. liczby czy tekst. Mogą być zwrócone lub przypisane do zmiennej. Aby wywołać funkcję, musisz zrobić to explicite przy użyciu nawiasów „()”. Wywołanie f1(), spowoduje stworzenie nowej funkcji (podobnie jak tworzone są zmienne), ale aby ją wywołać trzeba zrobić to własnoręcznie.

  • Slawek napisał(a):

    W ostatnim przykładzie co oznacza :”zwrócenie referencji do funkcji zadanie(), która zostanie przypisana zmiennej a”.

  • Dodaj komentarz

    Twój adres e-mail nie zostanie opublikowany.