Programování v jazyce JavaScript
Katedra softwarového inženýrství Fakulta informačních technologií České vysoké učení technické v Praze © Pavel Štěpán, 2011
Anonymní funkce BI-JSC
Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
P. Štěpán
PHP
BI-PHP, výpis 7
1/5
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Anonymni (lambda) funkce
<script type="text/javascript"> // anonymni funkce - nemaji jmeno var f = function(p1){ return p1+p2; } // lze pouzit jako parametry funkci nebo vracene hodnoty function volej(i,j,f){ f(i,j); } // volej(2,3,function(r,s){alert(r + s);}); // uzavery (closures): funkce, ktere maji pristup k promennym // z oboru platnosti jine fce (jsou to casto funkce, vytvorene // uvnitr jine fce) function createFunction(p1,p2){ return function(x){ return p1*x + p2; } } var vytvorena = createFunction (2,3); // alert(vytvorena(3)); /* I kdyz je funkce vracena, prirazena do promenne a pouzita na jinem miste, stale ma PRISTUP k promennym z vnejsi funkce (zde p1,p2). Pointer na retez oboru platnosti se priradi specielni interni vlastnosti, zvane [[Scope]] Retez oboru platnosti vnitrni funkce totiz obsahuje take obor platnosti vnejsi funkce. Ten tedy nemuze byt zrusen, dokud je platna vnitrni funkce. Uzavery tak s sebou nesou i obor platnosti rodicovske funkce mohou tedy zabirat vice pameti. Pozor na pouzivani promennych v uzaverech: uzaver obdrzi vzdy POSLEDNI hodnotu jakekoli promenne z rodicovske funkce: */ P. Štěpán
PHP
BI-PHP, výpis 7
2/5
function vytvorFunkce(){ var poleFunkci = new Array(); for (var i = 0; i < 10; i++){ poleFunkci[i] = function(){ return i; } } return poleFunkci; } var funkce = vytvorFunkce(); // alert(funkce[2]());
// 10 - posledni hodnota
// Zda se, ze kazda funkce bude vracet hodnotu sveho indexu. Ale ve // skutecnosti vraci kazda funkce 10 - aktualni hodnotu pomenne i // v dobe volani funkce - tedy az po skonceni cyklu. // Pokud chceme, aby i-ta funkce vracela i, muzeme si pomoci dalsi // anonymni funkci: function vytvorFunkce(){ var poleFunkci = new Array(); for (var i = 0; i < 10; i++){ poleFunkci[i] = function(num){ return function(){ return num; }; }(i); // okamzite volani prave vytvorene funkce!! } return poleFunkci; } funkce = vytvorFunkce(); // alert(funkce[4]()); // 4 /* anonymni funkce (ktera se ihned zavola - function(num){...}(i) s hodnotou i) ma jediny argument num, coz je hodnota, kterou chceme, aby funkce vracela. Argumenty se predavaji hodnotou, zkopiruje se do num aktualni hodnota i. Uvnitr anonymni fce se vytvori uzaver, ktery pristupuje k num - kazda funkce ma tedy svoji vlastni kopii num. pozor na this u anonymnich funkci: jsou povazovany za globalni, takze this vzdy ukazuje na object window (global), coz nemusi byt okamzite jasne: */ P. Štěpán
PHP
BI-PHP, výpis 7
3/5
var jmeno = "globalni"; var obj = { jmeno: "jmeno v objektu", fceZobrazJmeno: function(){ // metoda, ktera vraci anonymni fci return function(){ return this.jmeno; } } } // vraceni a okamzite zavolani vnitrni anonymni fce // ta je definovana v global, proto vraci SVE jmeno // alert(obj.fceZobrazJmeno()()); // globální // pro pristup k lokalnim promennym rodice nutno postupovat takto: var jmeno = "globalni"; var obj = { jmeno: "jmeno v objektu", fceZobrazJmeno: function(){ var thisLokalni = this; return function(){ return thisLokalni.jmeno; } } } alert(obj.fceZobrazJmeno()()); // jmeno v objektu /* Pozor v nekterych verzich IE: pouziva se nevhodny zpusob uvolnovani pameti pro objekty COM. A pokud na ne existuji odkazy prostrednictvim anonymnich funkci, tyto (casto velke) objekty se NEUVOLNI!! Simulace lokalnich promennych bloku pomoci anonymnich fci: JS definuje promenne v bloku vzdy na urovni rodicovske fce (nebo global). Napiseme-li ale (fomalni) definici a okamzite zavolani anonymni fce, promenne uvnitr ni se chovaji jako lokalni (tzv. soukromy obor platnosti): */ (function() { // blok s "lokalnimi" promennymi var z = "uvnitr"; // alert(z); } )(); // definice a okamzite vyvolani anonymni fce // alert(typeof lokalni); // undefined P. Štěpán
PHP
BI-PHP, výpis 7
4/5
// anonymni fce lze pouzit napr. i k definovani lokalnich // vlastnosti a metod objektu: (function(){ // privatni vlastnosti a metody // definovany pomoci var - lokalni v anonymni fci var privatniPromenna = 3; // "klasicka" definice fce - ty jsou vzdy privatni // v obklopujici fci function privatniFce(x){ return x + x; } // konstruktor - FUNKCNI VYRAZ (nikoli klasicka definice) // prirazen do promenne BEZ var - globalni MujObjekt = function(){ // prazdny konstruktor } // verejne metody MujObjekt.prototype.verejnaFce = function(){ return privatniFce(privatniPromenna++); // pouziva soukrome } })(); // ...() - okamzite zavolani var obj = new MujObjekt(); alert(obj.verejnaFce());
// konstruktor definovan globalne
P. Štěpán
PHP
BI-PHP, výpis 7
5/5