Pokazywanie postów oznaczonych etykietą anonymous function. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą anonymous function. Pokaż wszystkie posty

czwartek, 20 lipca 2017

example how and what for to use anonymous functions

I wrote some short introduction to anonymous function here, some time ago. I wrote some simple example, but no example for real life situation. Today I decided to write down an example which could be very useful on technical interview.

This is a very simple code example. We have a loop and inside this loop we create an array of functions. Every of functions logs i on the console. Then in the end we are calling the first function from the array.

var i = 0;
var funcArray = [];
for (; i < 20; i += 2) {
  funcArray.push(function() {
    console.log('i inside function', i);
  };
});

funcArray[0]();

What we want to achieve here is, to have an array of functions, to use inside of function a value of i. We cannot use index of function in array, as i is incremented by 2. This implementation looks like the easiest solution for our need.

So what would display on console as a result of this line funcArray[0]();? We expect it to be 0, but unfortunately it is... 20... WHY??

The answer is very easy - the scope. The thing which makes JavaScript harder to learn. But is very logic. Scope exists on function level (ES5) or on block level (ES6+). In this case inside of loop the function which uses scope variable i is created. But the function is called outside the loop, where i has a value 20 (the first value, which didn't meet the requirement, so there was no more incrementation of i).

So it doesn't matter which index would be called, the i outside of loop is always equal the first value, which didn't pass the condiition. It means we have to change the way how we create the scope for our function. And here the anonymous function will come with help.

What should be done, then? We have to create immediately invoked anonymous function, which will create the scope and will return the function which will be assigned to array element. As a parameter to anonymous function i will be passed to make it available inside the scope.

funcArray.push(( // immediately invoked function
// anonymous function, which gets i from scope as index
  function (index) {
    return function() { // returns a our function
      console.log('index inside function', index);
    }
  }
)(i)); // i passed to immediately invoked function

środa, 31 października 2012

funkcje w JavaScript, part 3 - samowywolujace sie funkcje

Czyli self-invoking functions. Coz to takiego? Tak na prawde to kontynuacja tematu o funkcjach anonimowych.

Jak wyglada samowywolujaca sie funkcja? Jest to anonimowa funkcja otoczona nawiasami okraglymi, po ktorych jest jeszcze jedna para nawiasow okraglych i srednik.
(
  function() {
    // cialo funkcji
  }
)();

Jak to dziala? Otoz sama definicja funkcji anonimowej nie wnosi nic. Kod sie nie wykona automagicznie. Pierwsza para nawiasow opakowuje funkcje anonimowa, jako kod wykonywalny, a druga sluzy do przekazywania parametrow. Dosc czesto mozna spotkac sie z nastepujacym zapisem:
(
  function ($) {
    // cialo funkcji
  }
)(jQuery);

Jest to jeden z wielu sposobow na unikniecie konfliktu w przestrzeni nazw, gdy uzywa sie wiecej niz jednej biblioteki pozwalajacej na uzywanie znaku $ jako nazwy zmiennej. W pokazanym przykladzie sytuacja jest bardzo czysta. Wewnatrz funkcji znak dolara istnieje tylko jako obiekt jQuery.

Powyzszy zapis ma jedna zasadnicza wade. Ten kod mozna wykonac tylko raz, poniewaz nie ma nazwy. Uzycie funkcji anonimowej eliminuje zasmiecanie globalnej przestrzeni nazw, ale rownoczesnie uniemozliwia powtorne wykorzystanie kodu. Do czego wiec uzywa sie samowolajacych sie funkcji? Ogolnie do ustawiania srodowiska, jest to operacja wykonywana zazwyczaj raz, przy inicjalizacji.

poniedziałek, 29 października 2012

funkcje w JavaScript, part 2 - funkcje anonimowe

We wczesniejszym poscie pisalam, ze funkcje mozna definiowac, jak zmienne. Tak wiec skoro zapis:
var a = 5;

jest poprawny, tak samo zapis:
var b = function(){};

tez jest poprawny. Ale idac za ciosem, zapis:
5;

tez jest poprawny, choc nic nie wnosi. Ot sama wartosc. W takim badz razie zapis:
function(){};

tez jest poprawny, choc w takiej postaci tez nic nie wnosi. Powyzsza definicja funkcji bez podania nazwy jest okreslana funkcja anonimowa (anonymous function).

Do czego mozna uzyc takiego tworu? Najczesciej przekazuje sie jako parametr do innej funkcji (funkcje sa danymi, wiec mozna je przekazywac jako parametry), tzw anonymous callback function, lub wywoluje w specyficzny sposob.

Anonymous callback function:
function fa () {

var a = 12;

var b = function(va, vb) {
  console.log("va = " + va);
  console.log("vb() returns " + vb());
}

b(a, function(){ return a + 2;});

}

fa();

Kod stosunkowo prosty. Ot mamy funkcje fa. W srodku definiujemy zmienna a oraz funkcje prywatna b (niewidoczna z zewnatrz, ale o tym w innym poscie). Funkcja b przyjmuje 2 parametry, drugi jest funkcja. Oba parametry wyswietla na konsoli. Nastepnie wolamy funkcje b przekazujac jako pierwszy parametr zmienna a, a jako drugi funkcje anonimowa w ktorej modyfikujemy a dodajac do niej 2. Na koncu wywolujemy fa.

I tu pojawia sie pytanie, po co przekazywac funkcje anonimowa jako parametr do innej funkcji? Przeciez mozna zapisac (a + 2) i przekazac jako zwykla liczbe. To oczywiscie byl prosty przyklad. Funkcja anonimowa dziala, jak kazda inna, ma swoj wlasny scope, ale i widzi zmienne ze srodowiska w ktorym sie znajduje. Daje nam to duze mozliwosci uzywania zmiennych dostepnych i manipulowania nimi bez zasmiecania przestrzeni nazw kolejna nazwa funkcji uzyta w jednym tylko miejscu. Opakowuje ladnie kod, dzieki czemu wprowadzanie zmian jest latwiejsze.

Wyobrazmy sobie, ze mamy tablice po ktorej sie iterujemy i kazdy element modyfikujemy. Iteracja po tablicach czy obiektach jest zasobozerna. Im wieksza tablica, tym wiekszy czas wykonania iteracji i tym wiecej zasobow jest wykorzystanych. Optymalizacja w takich wypadkach polega na tym, aby ograniczyc sie do jednej iteracji i zmniejszyc czas wykonania operacji na kazdym elemencie. Najszybciej wykonuje sie kod napisany inline, ale kazdy programista z choc minimalnym doswiadczeniem wie, jak trudno jest utrzymac kod napisany inline. Dlatego wykorzystuje sie funkcje anonimowe, ktore daja swoj narzut na wykonanie kodu, ale go rownoczesnie porzadkuja i ulatwiaja wprowadzanie zmian i utrzymanie.

Jak widac, powodow uzywania funkcji anonimowych jako parametrow jest wiele, najczesciej zwiazane sa one z optymalizacja kodu i/lub jego czytelnoscia.

A tutaj przykład użycia samowywołujacej się funkcji anonimowej