Stručně o funkcích
Každý, kdo někdy něco napsal v některém z běžných programovacích jazyků, zná funkce jako něco, co se někde definuje (případně ještě samostatně deklaruje, jako třeba v hlavičkových souborech u jazyka C) a někde jinde zavolá, často na více místech. Hlavním smyslem funkce je odstranit opakování téhož kódu všude, kde je potřeba – stačí ho napsat jen jednou.
V objektovém programování se hovoří o metodách. Ty jsou spjaty s objekty (jejich instancemi nebo třídami), jinak se na ně lze ale dívat jako na funkce. Ještě o nich bude řeč.
Když se v JavaScriptu definuje funkce, vytvoří se tím zvláštní objekt – instance třídy Function. To znamená, že lze nadefinovanou funkci předávat jako hodnotu identifikovanou svým názvem. Dokonce lze funkci nadefinovat i přímo v místě, kde se s ní dál pracuje („anonymní funkce“). Toto všechno poskytuje řadu možností, které výrazně usnadňují práci.
Funkce jako parametr
Tím, že je každá funkce instancí objektu, můžeme ji jako jakoukoli jinou objektovou instanci (třeba String
nebo RegExp
) někam předat. „Někam“ znamená samozřejmě do funkce či metody jako parametr (argument). Uvnitř dané funkce se předaná funkce volá podle potřeby.
K čemu je to dobré? Například k tomu, aby se funkce zavolala pro každý z nějakých zpracovávaných objektů a něco s ním udělala. V jQuery je takovým typickým příkladem metoda filter()
. Ta slouží k vyfiltrování některých objektů z původní množiny. Dá se použít selektor, ale například také právě funkce. Tady je příklad:
function myFilter(index, element) { if (index == 0) return false; return element.accessKey == '0'; } var a = $('#menu a').filter(myFilter);
Příklad přiřadí k dalšímu použití do proměnné a instanci jQuery
s vyfiltrovanými objekty odkazů. Nejprve si definujeme funkci myFilter()
, která bude zajišťovat filtraci. V tomto případě funguje tak, že první odkaz vždy zahodí a z dalších ponechá ty, které mají přístupovou klávesu „0“. Následně se takto definovaná funkce předá metodě filter()
, která zajistí její zavolání pro každý objekt v původní množině získané selektorem.
Každý si může zkusit funkci přepsat do elegantnější, byť méně názorné podoby. Místo dvou kroků lze vše řešit v jednom, v rámci výrazu poskytujícího návratovou hodnotu funkce.
Anonymní funkce
Většinou bývá lepší si funkci definovat „klasicky“, tedy pojmenovanou, jako je tomu výše. Existují ovšem případy, že je to zbytečné – funkce se používá jen na jediném místě a proto není na závadu ji definovat až přímo v místě použití.
$('textarea').val(function(index, value) { return 'Přeložte: ' + value; });
Máte například formulář s textovými oblastmi, kde chcete uživatele vyzvat, aby texty přeložil. Tak se ke každému jednoduše přidá příslušná instrukce. Metoda val()
před nastavením nové hodnoty každému objektu získá tuto hodnotu zavoláním anonymní funkce, tedy definované přímo v okamžiku volání.
Pro podobné jednoduché případy je to výborná věc, která brání zaplevelení globálního jmenného prostoru názvy drobných, jednorázově použitých funkcí. Máte-li v projektu takových funkcí stovky, při pojmenování každé by ani s našeptávačem ve vývojovém prostředí nemuselo být snadné se v tom vyznat.
Metoda jako parametr
Úplně stejně jako globální funkci lze použít i metodu – a to jak metodu definovanou přímo v konkrétní instanci, tak definovanou ve třídě (prototypu). Předá se pak identifikací instance a metody (tečkovou notací), případně přes proměnnou, pokud to má smysl. Tady je stručný příklad:
var o = { test: function() { … } }; obj.proc(o.test);
Přímo v instanci o se definuje metoda test()
, která něco dělá (není teď podstatné co). Metodě proc()
instance nějakého jiného objektu obj
se nadefinovaná metoda předá a ta s ní pak nějak nakládá.
Hlavní rozdíl metody oproti funkci je v tom, že má metoda přístup k datům (položkám) objektu. A teď přijde to důležité – v jQuery se obvykle funkce předaná jako parametr stane metodou nějakého objektu a tím získá přístup k nějakým dalším datům, které nejsou funkci předávána přes její parametry.
Když se vrátíme k té anonymní funkci z příkladu výše – tam metoda val()
udělá vlastně to, že se z předané funkce stane dočasně metoda instance objektové třídy Element
, čímž umožní k této instanci přistupovat, a to obvyklým způsobem, tedy přes this
. Příklad můžeme tedy rozšířit třeba takto:
$('textarea').val(function(index, value) { return 'Přeložte (' + this.name + '): ' + value; });
Funkce, tedy vlastně už metoda, si do objektu sáhne pro jeho název (atribut name
) a ten přidá do instrukce k přeložení. Budete-li tedy v jQuery předávat funkci jako parametr, vždycky si předem v dokumentaci zjistěte, k jakému objektu získáte přístup a co z něj lze využít. Lze si tím často dost usnadnit práci.
Obsluha událostí
Funkce předávané jako parametr se nejčastěji používají v jedné poměrně široké oblasti jQuery, a to je obsluha událostí. Mnoho věcí se totiž ve webové aplikaci odehrává asynchronně a proto je zcela nezbytné implementovat reakce na různé události, které iniciuje uživatel, webový prohlížeč nebo i samotná aplikace. Na to, jak to řešit, se podíváme příště.