Am amintit cand am vorbit prima data de JavaScript, de notiunea de inchidere. Aceasta notiune este esentiala in programarea functionala; cu toate ca nu am spus-o explicit atunci, dar JavaScript este un limbaj de programare functionala. MooTools face si mai usor folosirea conceptelor din programarea functionala, prin extinderea clasei native Function. Cei care nu au cunostinte de programare functionala s-ar putea sa nu inteleaga mare lucru din explicatiile de mai jos, asa ca, deocamdata, pot trece linistiti peste ele. Ne sunt puse astfel la dispozitie urmatoarele metode:
Function.passprimeste doi parametri: primul parametru poate fi un obiect sau un vector de obiecte, care sunt transmise ca argumente functiei, fara ca aceasta sa fie apelata, si un al doilea parametru, optional, care reprezinta un obiect la care este legata instanta luithisdin interiorul functiei (adica la fiecare folosire a luithisin interiorul functiei,thisva fi o referinta la acest al doilea parametru – pentru mai multe detalii vezi articolul Obiecte in JavaScript, discutia despreFunction.call). Rezultatul apelului acestei metode este o functie, care poate fi apelata mai tarziu in cod, fara argumente. Foarte important, daca functia initiala astepta ca parametru un vector, il putem pasa printr-un apel de genul:functie.pass([[1, 2, 3, 4]]);(deci transmitem ca parametru un vector cu un singur element, acest singur element avand tipulArray). Daca vi se pare confuz, haideti sa incercam un exemplu:
var plus = function(a, b) {
return a+b;
};
alert(plus(2,3)); // 5
var cinci = plus.pass([2,3]);
// observati ca trebuiau transmisi doi parametri,
// deci i-am pus intr-un vector
// cinci este o *functie*, diferita de plus,
// care are deja cei doi parametri stocati intern
// $type(variabila) intoarce tipul unei variabile
alert($type(cinci)); // function
alert(cinci()); // 5
alert($type(cinci())); // number
Din exemplul de mai sus este posibil sa observati si de ce atunci cand functia primeste un singur parametru pe care il asteapta ca fiind vector, e nevoie sa punem acel vector intr-un alt vector care contine un singur element: daca am pasa ca parametru [1,2], functiei i-ar fi trimisi 2 parametri, primul cu valoarea 1 si al doilea cu valoarea 2. Daca in schimb trimitem [[1,2]] functiei ii sunt trimise toate elementele din vector ca parametri, astfel ca functiei ii este trimis un singur parametru – pentru ca este vorba de un vector cu un singur element – si anume vectorul [1,2]
Function.attemptprimeste aceiasi parametri ca siFunction.call, dar de data aceasta functia este si apelata. Daca in mod normal functia arunca o exceptie,Function.attemptintoarcenullsi nu arunca exceptiile; altfel, este intors rezultatul apelului functiei. Astfel, daca folosim aceeasi functieplusde mai sus ca exemplu,plus()ar arunca o exceptie. Sa incercam un exemplu:
function first(v) {
return v[0];
};
alert(first([1])); // 1
alert(first()); // eroare!
alert(first.attempt([[1]])); // 1
// din nou, first asteapta ca unic parametru un vector
// (vezi mai sus de ce sunt folosite doua paranteze drepte)
alert(first.attempt()); // null
Function.bindleaga (eng. binds) referinta luithisdin codul unei functii, la primul parametru transmis. Al doilea parametru este acelasi cu primul parametru transmis luiFunction.passsiFunction.attempt, si este optional. Cu toate ca poate parea caFunction.bindeste doar un alias pentruFunction.call,Function.bind, la fel caFunction.pass, intoarce o noua functie, nu rezultatul apelului functiei. Exemplu:
var x='global';
var variabila = {
x: 'variabila'
};
function spune() {
alert('x: '+this.x);
};
spune(); // this == window, context global -> x: global
spune.call(variabila); // this == variabila -> x: variabila
var spune_legat = spune.bind(variabila);
alert($type(spune_legat)); // function
spune_legat(); // x: variabila
Daca o sa va uitati pe codul din cartea MooTools Essentials, scrisa de Aaron Newton (singura carte despre MooTools pana in acest moment, si care chiar merita citita), o sa vedeti ca in foarte multe exemple este folosit Function.bind. Motivul este acela ca IE6, al doilea cel mai folosit browser (din pacate), are o problema cu inchiderile (eng. closures – vezi Obiecte in JavaScript) care cauzeaza scurgeri de memorie (eng. memory leaks). E adevarat ca a aparut la un moment dat si un update, insa nu avem garantia ca toti utilizatorii unui site au toate update-urile la zi (daca ar fi atat de constiinciosi, nu ar folosi IE6 in primul rand), deci daca avem de-a face cu multe inchideri, este mai bine sa folosim Function.bind. (Cu toate ca inchiderile sunt o caracteristica foarte folositoare a JavaScript, si oricum nu putem folosi intotdeauna Function.bind; totusi, atunci cand putem, este recomandat sa il folosim.)
Function.bindWithEventeste identica cuFunction.bind, doar ca primul parametru care va fi transmis functiei, inainte de orice alt parametru transmis de noi, va fi o instantaEventcare a declansat un eveniment, iarFunction.bindWithEventeste folosita, evident, atunci cand lucram cu evenimente. Instanta deEventtransmisa este valabila si pentru IE, si este normalizata in asa fel ca putem folosi acelasi cod pentru toate browserele (deci am scapat de una din diferentele intre browsere, pana acum)Function.delaysiFunction.periodicalprimesc trei parametri, dintre care numai primul este obligatoriu: un interval de timpt(in ms), si cei doi parametri de care am mai vorbit laFunction.pass. Efectul acestora este ca vor apela functia cu o intarziere detms/ periodic la fiecaretms. Acestea sunt echivalente cusetTimeout/setPeriodical, cele doua functii native ale JavaScript, numai ca este mai OO ca acestea sa fie metode ale luiFunction, decat sa fie functii globale. Valoarea returnata de cele doua este un intreg, care poate fi folosit de functia (globala)$clear(in JavaScript,$este un caracter valid pentru nume de variabile) pentru a opri apelarea intarziata/periodica.$cleareste echivalent cu ambele functii nativeclearTimeoutsiclearPeriodical. Exemplu:
var n = 0;
function enervant() {
if (n>=5) {
$clear(enervant_periodic);
// acesta este unul din rarele cazuri
// in care nu putem folosi inchideri
// sau cel putin, este mai simplu decat
// sa incercam artificii pentru Function.bind
return;
}
n++;
alert('Enervant, nu-i asa?');
};
var enervant_periodic = enervant.periodical(500);
Function.runfunctioneaza la fel caFunction.attempt, doar ca exceptiile sunt aruncate.- in fine,
Function.createcreaza o copie a unei functii. Primeste un singur parametru – unObjectcare reprezinta optiuni, si este folositor atunci cand e nevoie sa folosim mai multe dintre metodele luiFunctiondeodata (de exemplu, vrem sa intarziem executia si sa folosim functia impreuna cu evenimente). Lista de parametri o gasiti in documentatia oficiala, si din tot ce am discutat pana acum ar trebui sa fi suficient de usor de inteles.
Totusi, exista un concept din programarea functionala – functii curry – care nu este implementat de MooTools. Un articol interesant in care autorul implementeaza o metoda Function.curry in MooTools este How about a nice, spicy curry? Din nou, acest articol este destinat celor familiari cu programarea functionala; oricum, daca cineva nu tine mortis sa foloseasca function currying, poate fi intotdeauna evitat.
Data viitoare, vom vorbi despre manipularea DOM folosind MooTools.

The Framework-uri JavaScript: Programare functionala in MooTools by Interfeţe Web, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 Romania License.
#1 by Dl. Petcu on 13/12/2008 - 14:28
foarte bun micul tutorial