Niedziela 19 Maj 2024r. Godz 00:00:00      
Postów: 251      

Funkcje w JavaScript

Funkcje są najpotężniejszym elementem JavaScript. Mogą pełnić rolę funkcji w języku C, metod oraz konstruktorów w C++/Java, a także klas wewnętrznych Javy lub funkcji lambda.

Funkcje w JS są „obywatelem pierwszej kategorii” (ang. first class objects) — mogą być tworzone w każdej chwili, przypisywane do obiektów, a nawet przekazywane jako argument do innych funkcji.

Są dwa sposoby, które używa się naprzemiennie. Zapis

 function nazwa(argument)
 {
 }

jest równoważny z:

 var nazwa = function(argument) {}

global scope po polsku? To chyba nie jest kod globalny. scope tłumaczy się (chyba) na zasięg, ale zasięg globalny brzmi dziwnie...

a może przestrzeń globalna ? to brzmi lepiej

Tworzenie funkcji ma różny efekt zależnie od kontekstu. W głównym (globalnym, poza funkcjami) kodzie tworzy funkcję jako nowe pole obiektu window, czyli ogólne dostępną funkcję globalną.

 function globalna() { return "to jest globalna funkcja" }
 alert(window.globalna);
 Alert wyświetli zawartość funkcji

Funkcje mają inne znaczenie przy tworzeniu klas i inaczej deklaruje się je przy obsłudze zdarzeń.

Funkcje mogą mieć dowolną, zmienną ilość argumentów. Nadmiarowe argumenty są ignorowane, a za brakujące podstawiana jest wartość undefined.

  function opcjonalny(argument1, argument2)
  {
    if (argument2 != undefined) alert("podano drugi argument")
  }
  
  opcjonalny("pierwszy")
  opcjonalny("pierwszy", "drugi")
  opcjonalny("pierwszy", "drugi", "zignorowany")

Zmienna lokalna arguments jest (pseudo) tablicą zawierającą wszystkie argumenty przekazane do funkcji.

  function dowolne(){
    for(var i = 0; arguments.length; ++i)
      alert('Argument: '+(i+1)+', wartość: '+ bez.arguments[i]);
  }
  dowolne("pierwszy", "drugi", "trzeci")

arguments.calee zawiera referencję do wywołanej funkcji. Umożliwia to funkcjom anonimowym rekurencyjne wywołanie samych siebie.

Jeżeli w ciele funkcji zostanie napotkane słowo kluczowe return, to funkcja kończy swoje wywołanie i zwraca wartość następującą po słowie return (zarówno typ prosty jak i obiekt). Jeżeli na słowie return nie ma podanej wartości lub w ciele funkcji nie występuje takie słowo w ogóle, to funkcja zwraca obiekt undefined.

 function dodaj(skladnik1, skladnik2)
 {
   return skladnik1+skladnik2;
   /* jakikolwiek kod tutaj nie zostanie już wykonany */
 }
 
 var cztery = dodaj(2,2);

JavaScript dopuszcza rzecz niespotykaną w innych językach — traktowanie funkcji jak obiekt. Można je przekazywać, przypisywać zmiennym, przypisywać do pól obiektów i robić z nimi wszystko to, co z każdym innym obiektem w JavaScript.

  function f1(a,b) {
    alert(a+b);
  }
function f2(a,b) { alert(a-b); }
var g = f1;
g(7,3); /* wyświetla "10" */
g = f2;
g(7,3); /* wyświetla "4" */

Wykorzystuje się tę cechę do implementacji klas i dziedziczenia oraz parametryzacji algorytmów (np. Array.sort(funkcja) jako parametr przyjmuje funkcję umożliwiając sortowanie wg własnych kryteriów).

 funkcja wykonaj(funkcjaDoWykonania)
 {
   funkcjaDoWykonania();
 }
var funkcja = function(){alert("Hello world");} wykonaj(funkcja)

Zmienne mogą mieć zasięg globalny lub lokalny. Zależy to od miejsca deklaracji. Jeżeli zmienna została zadeklarowana (var nazwa_zmiennej;) poza funkcją to posiada zasięg globalny. Zmienna zadeklarowana w funkcji posiada zasięg lokalny, czyli nie jest dostępna poza funkcją.

 var x = 7;
 function test() 
 {
   var x = 1;
   return function(){x++;alert(x);}
 }
 var licznik = test()
 licznik();
 licznik();
 alert(x)

Powyższy kod działa następująco:

  • tworzy zmienną x równą 7
  • tworzy funkcję test()
  • w funkcji test() tworzy nową zmienną x
  • tworzy i zwraca anonimową funkcję
  • która następnie jest zapamiętywana w zmiennej licznik
  • i wywołana dwukrotnie
  • alert() poda wartość zmiennej x zdefiniowanej na początku

Efekt będzie taki, że kod poda najpierw liczby 2, 3, a potem 7. Stanie się tak dlatego, że funkcja licznik(), która powstała wewnątrz funkcji test() będzie cały czas się odwoływała do x wewnątrz test(), zamiast do „globalnego” x na zewnątrz funkcji. Natomiast alert(x) poza funkcją test() nie „widzi” jej wewnętrznej zmiennej i użyje tej zadeklarowanej na zewnątrz.