Funkce jsou jedním z nejdůležitějších stavebních bloků kódu v JavaScriptu.

Funkce se skládají ze sady příkazů a obvykle provádějí jeden konkrétní úkol (například sčítání čísel, výpočet odmocniny atd.).

Kód umístěný ve funkci bude proveden pouze po explicitním volání této funkce.

Deklarace funkce

1.Syntax:

//Funkce deklarace funkce FunctionName(var1, var2)( Kód funkce ) //Volání funkce FunctionName(var1,var2);

2. Syntax:

//Deklarace funkce var functionname=function(var1, var2)(Kód funkce) //Volání funkce functionname(var1,var2);

název funkce určuje název funkce. Každá funkce na stránce musí mít jedinečný název. Název funkce musí být zadán latinkou a nesmí začínat čísly.

za1 a za2 jsou proměnné nebo hodnoty, které lze předávat uvnitř funkce. Každé funkci lze předat neomezený počet proměnných.

Poznámka: i když funkci nejsou předány žádné proměnné, nezapomeňte za název funkce vložit závorky "()".

Poznámka: Názvy funkcí v JavaScriptu rozlišují velká a malá písmena.

Příklad funkce JavaScript

Funkce messageWrite() v příkladu níže se spustí až po kliknutí na tlačítko.

Poznámka: tento příklad používá událost onclick. Události JavaScriptu bude podrobně diskutováno později v tomto tutoriálu.

Předávání proměnných funkcím

Do funkcí můžete předat neomezený počet proměnných.

Poznámka: všechny manipulace s proměnnými uvnitř funkcí se ve skutečnosti neprovádějí na proměnných samotných, ale na jejich kopii, takže obsahy samotných proměnných se v důsledku provádění funkcí nemění.

/* Definuje funkci, která přidá 10 k předané proměnné a vydá výsledek na stránku */ function plus(a)( a=a+10; document.write("Výstup funkce: " + a+"
"); ) var a=25; document.write("Hodnota proměnné před voláním funkce: "+a+"
"); // Zavolejte funkci, která jí předá proměnnou plus(a); document.write("Hodnota proměnné po volání funkce: "+a+"
");

Rychlý pohled

Chcete-li přistupovat ke globální proměnné z funkce spíše než z její kopie, použijte window.variable_name.

Funkce plus(a)( window.a=a+10; ) var a=25; document.write("Hodnota proměnné před voláním funkce: "+a+"
"); plus(a); document.write("Hodnota proměnné po volání funkce: "+a+"
");

Rychlý pohled

návratový příkaz

S příkazem vrátit se Můžete vrátit hodnoty z funkcí.

Rychlý pohled

Vestavěné funkce

Kromě uživatelsky definovaných funkcí v JavaScriptu existují také vestavěné funkce.

Například vestavěná funkce je Konečný umožňuje zkontrolovat, zda je předaná hodnota platné číslo.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90,33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("Toto je řetězec")+"
");

Rychlý pohled

Poznámka: úplný seznam vestavěné funkce JavaScriptu najdete v našem .

Lokální a globální proměnné

Volají se proměnné vytvořené uvnitř funkcí lokální proměnné. K takovým proměnným máte přístup pouze v rámci funkcí, ve kterých byly definovány.

Po provedení kódu funkce jsou takové proměnné zničeny. To znamená, že proměnné se stejným názvem mohou být definovány v různých funkcích.

Volají se proměnné, které jsou vytvořeny mimo funkční kód globální proměnné k těmto proměnným lze přistupovat odkudkoli v kódu.

Pokud deklarujete proměnnou bez var uvnitř funkce, stane se také globální.

Globální proměnné jsou zničeny pouze při zavření stránky.

Rychlý pohled

Poznámka: při zobrazení bude var2 mít hodnotu null, protože funkce func1 funguje na místní "verzi" var2.

Použití anonymních funkcí

Jsou volány funkce, které při deklaraci neobsahují název anonymní.

Anonymní funkce jsou v zásadě deklarovány ne pro jejich následné volání z kódu jako běžné funkce, ale pro předání jiným funkcím jako parametr.

Funkce arrMap(arr,func)( var res=nové pole; for (var i=0;i ");

Rychlý pohled

Udělej si sám

Cvičení 1. Opravte chyby v kódu níže:

Cvičení 1

Opravte chybu v kódu.

Úkol 2.

  1. Reprodukujte kód funkcí 1-3 zkoumáním jejich chování při předávání různých parametrů.
  2. Určete klíčové slovo interakcí s funkcí 4.

Úkol 2

//Zavolání první tajné funkce document.write(secfunc1(4,12) + "
"); // Volání druhé tajné funkce document.write(secfunc2(100,10) + "
"); //Zavolání třetí tajné funkce secfunc3(23,10); document.write("
"); // Volání čtvrté tajné funkce secfunc4("n");

Chcete-li používat systém komentářů Disqus, povolte JavaScript.

Lidé si myslí, že informatika je umění pro génia. Ve skutečnosti je opak pravdou – jen spousta lidí dělá věci, které stojí na sobě, jako by tvořily zeď z malých oblázků.

Donald Knuth

Volání funkcí, jako je upozornění, jste již viděli. Funkce jsou chlebem a máslem programování v JavaScriptu. Myšlenka zabalit část programu a nazvat ji jako proměnná je velmi populární. Je to nástroj pro strukturování velkých programů, omezení opakování, přiřazování jmen podprogramům a izolování podprogramů od sebe navzájem.

Nejviditelnější použití funkcí je vytvoření nového slovníku. Vymýšlet slova pro běžnou lidskou prózu je špatná forma. V programovacím jazyce je to nutné.

Průměrný dospělý ruský mluvčí zná asi 10 000 slov. Vzácný programovací jazyk obsahuje 10 000 vestavěných příkazů. A slovní zásoba programovacího jazyka je jasněji definovaná, takže je méně flexibilní než lidský. Proto k němu většinou musíme přidat vlastní slova, abychom se vyhnuli zbytečnému opakování.

Definice funkce

Definice funkce je normální definice proměnné, kde hodnota, kterou proměnná přijímá, je funkce. Například následující kód definuje proměnnou čtverec, který odkazuje na funkci, která vypočítá druhou mocninu daného čísla:

var square = funkce(x) ( return x * x; ); console.log(čtverec(12)); // → 144

Funkce je vytvořena výrazem začínajícím klíčovým slovem function. Funkce mají sadu parametrů (v tomto případě pouze x) a tělo obsahující instrukce, které se mají provést při volání funkce. Tělo funkce je vždy uzavřeno ve složených závorkách, i když se skládá z jediného příkazu.

Funkce může mít několik parametrů nebo žádný. V následujícím příkladu makeNoise nemá seznam parametrů, zatímco power má dva:

Var makeNoise = function() ( console.log("Kurva!"); ); dělat hluk(); // → Sakra! var mocnina = funkce (základ, exponent) ( var výsledek = 1; pro (počet var = 0; počet< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Některé funkce vracejí hodnotu, jako je mocnina a druhá mocnina, jiné ne, jako makeNoise, což má pouze vedlejší efekt. Příkaz return definuje hodnotu vrácenou funkcí. Když zpracování programu dosáhne této instrukce, okamžitě opustí funkci a vrátí tuto hodnotu na místo v kódu, odkud byla funkce volána. return bez výrazu vrací undefined .

Parametry a rozsah

Parametry funkce jsou stejné jako proměnné, ale jejich počáteční hodnoty se nastavují při volání funkce, nikoli v jejím kódu.

Důležitou vlastností funkcí je, že proměnné vytvořené v rámci funkce (včetně parametrů) jsou v rámci této funkce lokální. To znamená, že v mocenském příkladu se proměnná result vytvoří při každém volání funkce a tyto její samostatné inkarnace spolu nijak nesouvisí.

Tato lokalita proměnných platí pouze pro parametry a proměnné vytvořené uvnitř funkcí. Proměnné nastavené mimo jakoukoli funkci se nazývají globální proměnné, protože jsou viditelné v celém programu. K takovým proměnným můžete také přistupovat v rámci funkce, pokud jste nedeklarovali lokální proměnnou se stejným názvem.

Následující kód to ilustruje. Definuje a volá dvě funkce, které přiřazují hodnotu x. První ji deklaruje jako lokální, čímž změní pouze lokální proměnnou. Druhý nedeklaruje, takže práce s x uvnitř funkce odkazuje na globální proměnnou x, která byla nastavena na začátku příkladu.

var x = "venku"; var f1 = function() ( var x = "uvnitř f1"; ); f1(); konzolový log(x); // → vně var f2 = function() ( x = "uvnitř f2"; ); f2(); konzolový log(x); // → uvnitř f2

Toto chování pomáhá zabránit náhodné interakci mezi funkcemi. Pokud by byly kdekoli v programu použity všechny proměnné, bylo by velmi obtížné zajistit, aby jedna proměnná nebyla použita pro různé účely. A pokud byste proměnnou znovu použili, narazili byste na podivné efekty, kdy si kód třetí strany pohrává s hodnotami vaší proměnné. Tím, že zachází s proměnnými lokálními pro funkce tak, že existují pouze v rámci funkce, jazyk umožňuje pracovat s funkcemi, jako by to byly samostatné malé vesmíry, což vám umožňuje nestarat se o celý kód jako celek.

Vnořené obory

JavaScript nerozlišuje pouze mezi globálními a lokálními proměnnými. Funkce mohou být definovány v rámci funkcí, což vede k několika úrovním lokality.

Například následující poněkud nesmyslná funkce obsahuje uvnitř další dvě:

var landscape = function() ( var result = ""; var flat = function(size) ( for (var count = 0; count< size; count++) result += "_"; }; var mountain = function(size) { result += "/"; for (var count = 0; count < size; count++) result += """; result += "\\"; }; flat(3); mountain(4); flat(6); mountain(1); flat(1); return result; }; console.log(landscape()); // → ___/""""\______/"\_

Funkce rovina a hora vidí výslednou proměnnou, protože jsou uvnitř funkce, ve které je definována. Nemohou však navzájem vidět početní proměnné, protože proměnné jedné funkce jsou mimo rozsah druhé. A prostředí mimo krajinnou funkci nevidí žádnou z proměnných definovaných uvnitř této funkce.

Stručně řečeno, v každém místním rozsahu můžete vidět všechny obory, které jej obsahují. Množina proměnných dostupných uvnitř funkce je určena místem, kde je tato funkce v programu deklarována. Všechny proměnné z bloků obklopujících definici funkce jsou viditelné – včetně těch, které jsou definovány na nejvyšší úrovni v hlavním programu. Tento přístup k oborům se nazývá lexikální.

Lidé, kteří studovali jiné programovací jazyky, by si mohli myslet, že jakýkoli blok uzavřený ve složených závorkách vytváří své vlastní místní prostředí. Ale v JavaScriptu vytvářejí rozsah pouze funkce. Můžete použít samostatné bloky:

var něco = 1; ( var něco = 2; // Udělejte něco s proměnnou něco... ) // Ukončit blok...

Ale něco uvnitř bloku je stejná proměnná jako venku. Ačkoli jsou takové bloky povoleny, má smysl je používat pouze pro příkazy if a smyčky.

Pokud se vám to zdá divné, zdá se to tak nejen vám. JavaScript 1.7 zavedl klíčové slovo let, které funguje jako var, ale vytváří proměnné, které jsou lokální pro jakýkoli daný blok, nejen pro funkci.

Funguje jako hodnoty

Názvy funkcí se obvykle používají jako název části programu. Taková proměnná je jednou nastavena a nemění se. Je tedy snadné splést si funkci s jejím názvem.

Ale to jsou dvě různé věci. Volání funkce lze použít jako jednoduchou proměnnou – lze je například použít v libovolném výrazu. Je možné uložit volání funkce do nové proměnné, předat ji jako parametr jiné funkci a podobně. Také proměnná, která ukládá volání funkce, zůstává běžnou proměnnou a její hodnotu lze změnit:

Var launchMissiles = function(value) (​missileSystem. launch("prosím!"); ); if (safeMode) launchMissiles = function(value) (/* release */);

V kapitole 5 probereme úžasné věci, které lze provést předáním volání funkcí jiným funkcím.

Deklarace funkce

Existuje kratší verze výrazu „var square = funkce…“. Klíčové slovo funkce lze použít na začátku příkazu:

funkce square(x) ( return x * x; )

Toto je deklarace funkce. Příkaz definuje proměnnou square a přiřadí jí danou funkci. Zatím je vše ok. V takové definici je pouze jedno úskalí.

Console.log("Budoucnost říká:", future()); function future() ( return "STÁLE nemáme létající auta."; )

Tento kód funguje, i když je funkce deklarována pod kódem, který ji používá. Je to proto, že deklarace funkcí nejsou součástí běžného provádění programů shora dolů. "Přesunou" se na vrchol svého rozsahu a mohou být volány jakýmkoli kódem v tomto rozsahu. To je někdy výhodné, protože můžete napsat kód v pořadí, které dává největší smysl, aniž byste se museli starat o to, abyste museli definovat všechny výše uvedené funkce, kde se používají.

Co se ale stane, když umístíme deklaraci funkce do podmíněného bloku nebo smyčky? Nemusíte to dělat. Historicky různé platformy pro spouštění JavaScriptu řešily takové případy odlišně a současný jazykový standard to zakazuje. Pokud chcete, aby vaše programy běžely konzistentně, používejte deklarace funkcí pouze uvnitř jiných funkcí nebo hlavního programu.

Příklad funkce() ( funkce a() () // Normule if (něco) ( funkce b() () // Ay-yy-yy! ) )

zásobník hovorů
Je užitečné podívat se blíže na to, jak pracuje příkaz k provedení s funkcemi. Zde je jednoduchý program s několika voláními funkcí:

Funkce pozdrav(kdo) ( console.log("Ahoj, " + kdo); ) pozdrav("Semyon"); console.log("Pokeda");

Zpracovává se asi takto: volání pozdravu způsobí skok na začátek funkce. Zavolá vestavěnou funkci console.log, která převezme řízení, udělá svou věc a vrátí řízení. Poté dorazí na konec pozdravu a vrátí se na místo, odkud bylo voláno. Další řádek znovu volá console.log.

Schematicky to lze znázornit takto:

Top pozdrav console.log pozdrav top console.log top

Protože se funkce musí vrátit tam, odkud byla volána, musí si počítač pamatovat kontext, ze kterého byla funkce volána. V jednom případě by se měl console.log změnit zpět na pozdrav. V jiném se vrátí na konec programu.

Místo, kde si počítač pamatuje kontext, se nazývá zásobník. Pokaždé, když je funkce volána, aktuální kontext se přesune na vrchol zásobníku. Když se funkce vrátí, vytáhne horní kontext ze zásobníku a použije jej k pokračování.

Zásobníkové úložiště vyžaduje místo v paměti. Když se zásobník příliš zvětší, počítač přestane provádět a vydá něco jako „přetečení zásobníku“ nebo „příliš mnoho rekurze“. Následující kód to demonstruje – klade počítači velmi složitou otázku, která vede k nekonečným skokům mezi dvěma funkcemi. Přesněji by to byly nekonečné skoky, pokud by počítač měl nekonečný zásobník. Ve skutečnosti zásobník přeteče.

Funkce chicken() ( return egg(); ) function egg() ( return chicken(); ) console.log(chicken() + "přišel jako první."); // → ??

Nepovinné argumenty
Následující kód je zcela legální a běží bez problémů:

Alert("Ahoj", "Dobrý večer", "Ahoj všichni!");

Oficiálně má funkce jeden argument. Když je však takto vyzvána, nestěžuje si. Ignoruje zbytek argumentů a zobrazí "Ahoj".

JavaScript je velmi shovívavý k počtu argumentů předávaných funkci. Pokud projdete příliš mnoho, další budou ignorovány. Příliš málo – chybějícím bude přiřazena hodnota nedefinovaná.

Nevýhodou tohoto přístupu je, že je možné – a dokonce pravděpodobné – předat funkci nesprávný počet argumentů a nikdo si na to nebude stěžovat.

Výhodou je, že můžete vytvářet funkce, které přebírají volitelné argumenty. Například v další verzi mocninné funkce ji lze volat jak se dvěma, tak s jedním argumentem – v druhém případě bude exponent roven dvěma a funkce funguje jako čtverec.

Mocnina funkce (základ, exponent) ( if (exponent == nedefinováno) exponent = 2; výsledek var = 1; pro (počet var = 0; počet< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

V další kapitole uvidíme, jak vám tělo funkce může říct přesný počet argumentů, které jí byly předány. To je užitečné, protože umožňuje vytvořit funkci, která přebírá libovolný počet argumentů. Například console.log používá tuto vlastnost a vytiskne všechny argumenty, které mu byly předány:

Console.log("R", 2, "D", 2); // → R 2 D 2

Uzávěry

Schopnost používat volání funkcí jako proměnné ve spojení se skutečností, že lokální proměnné jsou znovu vytvořeny pokaždé, když je funkce volána, nás přivádí k zajímavému bodu. Co se stane s lokálními proměnnými, když funkce selže?

Následující příklad ilustruje tento problém. Deklaruje funkci wrapValue, která vytvoří lokální proměnnou. Potom vrátí funkci, která přečte tuto lokální proměnnou a vrátí její hodnotu.

Funkce wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); log konzole(wrap1()); // → 1 console.log(wrap2()); // → 2

To platí a funguje jak má – přístup k proměnné zůstává. Kromě toho může současně existovat více instancí stejné proměnné, což dále potvrzuje skutečnost, že místní proměnné jsou znovu vytvořeny s každým voláním funkce.

Tato schopnost pracovat s odkazem na nějakou instanci lokální proměnné se nazývá uzavření. Funkce, která uzavírá lokální proměnné, se nazývá uzavírací funkce. Nejen, že vás zbaví starostí s proměnlivou životností, ale také vám umožní používat funkce kreativně.

S mírnou změnou převedeme náš příklad do funkce, která násobí čísla libovolným daným číslem.

Funkce multiplikátor(faktor) ( return function(number) ( return number * factor; ); ) var double = multiplier(2); console.log(dvakrát(5)); // → 10

Samostatná proměnná jako localVariable z příkladu wrapValue již není potřeba. Protože parametr je sám o sobě lokální proměnnou.

Chce to cvik, abyste začali takto přemýšlet. Dobrou verzí mentálního modelu je představit si, že funkce zmrazí kód ve svém těle a zabalí jej do balíčku. Když uvidíte funkci return(...) (...), představte si ji jako ovládací panel pro část kódu zmrazenou pro pozdější použití.

V našem příkladu multiplikátor vrací zmrazený kus kódu, který ukládáme do proměnné double. Poslední řádek volá funkci obsaženou v proměnné, která aktivuje uložený kód (návratové číslo * faktor;). Stále má přístup k proměnné faktor, která byla definována při volání multiplikátoru, a má také přístup k argumentu předávanému během unfreeze (5) jako číselnému parametru.

rekurze

Funkce se může dobře volat sama, pokud se postará o to, aby nepřetekla zásobník. Taková funkce se nazývá rekurzivní. Zde je příklad alternativní implementace umocňování:

Funkce power(základ, exponent) ( if (exponent == 0) return 1; else return base * power(base, exponent - 1); ) console.log(power(2, 3)); // → 8

Takto matematici definují umocňování a možná to tento koncept popisuje elegantněji než cyklus. Funkce volá sama sebe mnohokrát s různými argumenty, aby se dosáhlo vícenásobného násobení.

Tato implementace má ale problém – v běžném prostředí JavaScriptu je 10x pomalejší než verze se smyčkou. Opakování je levnější než volání funkce.

Dilema rychlost versus elegance je docela zajímavé. Mezi lidským pohodlím a pohodlím strojů existuje určitá propast. Jakýkoli program lze urychlit tím, že bude větší a složitější. Programátor je povinen najít správnou rovnováhu.

V případě prvního umocňování je neelegantní smyčka docela jednoduchá a přímočará. Nemá smysl to nahrazovat rekurzí. Často však programy pracují s tak složitými koncepty, že člověk chce snížit efektivitu zvýšením čitelnosti.

Základní pravidlo, které již bylo mnohokrát opakováno a se kterým zcela souhlasím – nestarejte se o výkon, dokud si nebudete jisti, že se program zpomaluje. Pokud ano, najděte díly, které vydrží nejdéle, a vyměňte eleganci za efektivitu tam.

Samozřejmě bychom neměli hned úplně ignorovat výkon. V mnoha případech, stejně jako u umocňování, z elegantních řešení mnoho jednoduchosti nezískáme. Někdy zkušený programátor hned vidí, že jednoduchý přístup nebude nikdy dost rychlý.

Uvádím to, protože příliš mnoho začínajících programátorů lpí na efektivitě i v malých věcech. Výsledek je větší, složitější a často není bez chyb. Takové programy se zapisují déle a často nepracují o moc rychleji.

Ale rekurze není vždy jen méně efektivní alternativou smyček. Některé problémy se snáze řeší rekurzí. Nejčastěji se jedná o průchod několika větví stromu, z nichž každá se může větvit.

Zde je hádanka pro vás: můžete získat nekonečný počet čísel, počínaje číslem 1 a pak buď sečtením 5, nebo vynásobením 3. Jak napíšeme funkci, která se při daném čísle pokusí najít posloupnost takových sčítání a násobení, které vedou k danému číslu? Například číslo 13 lze získat tak, že nejprve vynásobíte 1 3 a poté dvakrát přičtete 5. A číslo 15 je obecně nemožné takto získat.

Rekurzivní řešení:

Funkce findSolution(target) ( funkce find(start, historie) ( if (start == target) return history; else if (start > target) return null; else return find (start + 5, "(" + history + " + 5)") || find(start * 3, "(" + historie + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

Tento příklad nemusí nutně najít nejkratší řešení – vyhovuje všem. Neočekávám, že okamžitě pochopíte, jak program funguje. Pojďme ale k závěru tohoto skvělého cvičení rekurzivního myšlení.

Vnitřní hledání funkce je rekurzivní. Vyžaduje dva argumenty – aktuální číslo a řetězec, který obsahuje záznam o tom, jak jsme k tomuto číslu dospěli. A vrátí buď řetězec ukazující naši sekvenci kroků, nebo hodnotu null.

K tomu funkce provede jednu ze tří akcí. Pokud se dané číslo rovná cíli, pak současná historie je právě způsob, jak toho dosáhnout, a proto se vrací. Pokud dané číslo více účel, nemá smysl dále násobit a sčítat, protože takto bude jen přibývat. A pokud jsme ještě nedosáhli cíle, funkce zkouší obě možné cesty od daného čísla. Přivolá se dvakrát, jednou každým ze způsobů. Pokud první volání nevrátí hodnotu null, vrátí se. V opačném případě se vrátí druhý.

Abychom lépe pochopili, jak funkce dosahuje požadovaného efektu, podívejme se na její volání, která se vyskytují při hledání řešení pro číslo 13.

Find(1; "1") find(6, "(1 + 5)") find(11, "((1 + 5) + 5)") find(16, "((1 + 5) + 5 ) + 5)") příliš velký nález(33, "(((1 + 5) + 5) * 3)") příliš velký nález(18, "((1 + 5) * 3)") příliš velký nález( 3, "(1 * 3)") najít (8, "(1 * 3) + 5)") najít (13, "(((1 * 3) + 5) + 5)") nalezeno!

Odsazení ukazuje hloubku zásobníku volání. Poprvé se funkce find zavolá dvakrát, aby zkontrolovala řešení začínající (1 + 5) a (1 * 3). První volání hledá řešení začínající na (1 + 5) a pomocí rekurze kontroluje všechna řešení, která poskytují číslo menší nebo rovné požadovanému číslu. Nenajde a vrátí hodnotu null. Potom operátor || a skočí na volání funkce, která prozkoumá možnost (1 * 3). Zde máme štěstí, protože ve třetím rekurzivním volání dostaneme 13. Toto volání vrátí řetězec a každý z || předá tento řetězec výše po cestě a ve výsledku vrátí řešení.

Grow Functions

Existují dva víceméně přirozené způsoby, jak zavést funkce do programu.

Nejprve napíšete podobný kód vícekrát. Tomu je třeba se vyhnout – více kódu znamená více prostoru pro chyby a více materiálu pro čtení pro ty, kteří se snaží program pochopit. Takže vezmeme opakující se funkcionalitu a přizpůsobíme ji dobré jméno a vložte jej do funkce.

Druhým způsobem je, že objevíte potřebu nějaké nové funkce, která stojí za to umístit do samostatné funkce. Začnete názvem funkce a poté napíšete její tělo. Můžete dokonce začít napsáním kódu, který funkci používá, ještě před tím, než je funkce samotná definována.

Jak obtížné je pro vás funkci pojmenovat, ukazuje, jak dobře rozumíte její funkčnosti. Vezměme si příklad. Potřebujeme napsat program, který vypíše dvě čísla, počet krav a kuřat na farmě, za nimiž budou následovat slova „krávy“ a „kuřata“. K číslům vpředu musíte přidat nuly, aby každé obsadilo přesně tři pozice.

007 Krávy 011 Slepice

Je zřejmé, že potřebujeme funkci se dvěma argumenty. Začněme kódovat.
// funkce printFarmInventory printFarmInventory(krávy, kuřata) ( var cowString = String(krávy); while (cowString.length< 3) cowString = "0" + cowString; console.log(cowString + " Коров"); var chickenString = String(chickens); while (chickenString.length < 3) chickenString = "0" + chickenString; console.log(chickenString + " Куриц"); } printFarmInventory(7, 11);

Pokud k řetězci přidáme .length, dostaneme jeho délku. Ukázalo se, že smyčky while přidávají k číslům úvodní nuly, dokud nedostanou řetězec 3 znaků.

Připraveno! Ale jakmile se chystáme poslat kód farmáři (samozřejmě spolu s tučnou kontrolou), zavolá a řekne nám, že má na farmě prasata a mohli bychom přidat výstup počtu prasat do programu?

Samozřejmě je to možné. Ale když začneme kopírovat a vkládat kód z těchto čtyř řádků, uvědomíme si, že se musíme zastavit a přemýšlet. Musí existovat lepší způsob. Snažíme se program vylepšit:

// outputZeroPaddedWithLabel funkce printZeroPaddedWithLabel(číslo, štítek) ( var numberString = String(číslo); while (numberString.length< 3) numberString = "0" + numberString; console.log(numberString + " " + label); } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { printZeroPaddedWithLabel(cows, "Коров"); printZeroPaddedWithLabel(chickens, "Куриц"); printZeroPaddedWithLabel(pigs, "Свиней"); } printFarmInventory(7, 11, 3);

Funguje! Název printZeroPaddedWithLabel je ale trochu zvláštní. Spojuje tři věci – výstup, nulové odsazení a štítek – do jedné funkce. Místo toho, abychom celý opakující se fragment nacpali do funkce, zdůrazněme jeden koncept:

// přidání funkce nul zeroPad(číslo, šířka) ( var string = String(číslo); while (string.length< width) string = "0" + string; return string; } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { console.log(zeroPad(cows, 3) + " Коров"); console.log(zeroPad(chickens, 3) + " Куриц"); console.log(zeroPad(pigs, 3) + " Свиней"); } printFarmInventory(7, 16, 3);

Funkce s pěkným, popisným názvem zeroPad usnadňuje pochopení kódu. A dá se použít v mnoha situacích, nejen v našem případě. Například pro zobrazení formátovaných tabulek s čísly.

Jak chytré a všestranné by měly být funkce? Můžeme psát jako nejjednodušší funkce, který doplňuje číslo nulami až na tři pozice, a efektní univerzální funkci formátování čísel, která podporuje zlomky, záporná čísla, zarovnání teček, doplněk různé symboly, atd.

Dobrým pravidlem je přidat pouze funkce, které rozhodně potřebujete. Někdy je lákavé vytvořit obecné rámce pro každou malou potřebu. Odolejte mu. Nikdy nedokončíte práci, ale stačí napsat hromadu kódu, který nikdo nepoužije.

Funkce a vedlejší účinky

Funkce lze zhruba rozdělit na ty, které jsou volány kvůli jejich vedlejším účinkům, a ty, které jsou volány, aby získaly nějakou hodnotu. Samozřejmě je také možné tyto vlastnosti kombinovat v jedné funkci.

První pomocná funkce v příkladu farmy, printZeroPaddedWithLabel, je volána kvůli vedlejšímu efektu tisku řetězce. Druhý, zeroPad, kvůli návratové hodnotě. A není náhoda, že druhá funkce přijde vhod častěji než ta první. Funkce, které vracejí hodnoty, se dají snáze kombinovat než funkce, které vytvářejí vedlejší efekty.

Čistá funkce je speciální druh funkce vracející hodnotu, která nejenže nemá žádné vedlejší účinky, ale také nezávisí na vedlejších účincích zbytku kódu – například nepracuje s globálními proměnnými, které lze náhodně změnit. někde jinde. Čistá funkce, když je volána se stejnými argumenty, vrací stejný výsledek (a nedělá nic jiného) - což je docela příjemné. Je snadné s ní pracovat. Volání takové funkce může být mentálně nahrazeno výsledkem její práce, aniž by se změnil význam kódu. Když chcete takovou funkci otestovat, můžete ji jednoduše zavolat a být si jisti, že pokud funguje v tomto kontextu, bude fungovat v jakékoli. Ne tak čisté funkce mohou vracet různé výsledky v závislosti na mnoha faktorech a mají vedlejší účinky, které se obtížně testují a zohledňují.

Člověk by se však neměl stydět psát funkce, které nejsou zcela čisté, nebo od takových funkcí zahájit posvátné čištění kódu. Vedlejší účinky jsou často užitečné. Není jak psát čistá verze console.log a tato funkce je docela užitečná. Některé operace lze snadněji vyjádřit pomocí vedlejších účinků.

Výsledek

Tato kapitola vám ukázala, jak psát své vlastní funkce. Když je klíčové slovo funkce použito jako výraz, vrátí ukazatel na volání funkce. Při použití jako příkaz můžete proměnnou deklarovat tak, že k ní přiřadíte volání funkce.

Klíčem k pochopení funkcí jsou místní rozsahy. Parametry a proměnné deklarované uvnitř funkce jsou pro ni lokální, znovu se vytvářejí při každém jejím volání a nejsou viditelné zvenčí. Funkce deklarované uvnitř jiné funkce mají přístup k jejímu rozsahu.

Je velmi užitečné rozdělit různé úkoly prováděné programem do funkcí. Nemusíte se opakovat, funkce dělají kód čitelnějším tím, že jej rozdělují na sémantické části, stejně jako kapitoly a části knihy pomáhají organizovat prostý text.

Cvičení

Minimální
V předchozí kapitole byla zmíněna funkce Math.min, která vrací nejmenší ze svých argumentů. Nyní si takovou funkci můžeme napsat sami. Napište funkci min, která vezme dva argumenty a vrátí minimum z nich.

Console.log(min(0, 10)); // → 0 console.log(min(0, -10)); // → -10

rekurze
Viděli jsme, že operátor % (zbytek) lze použít k určení, zda je číslo sudé (% 2). Zde je další způsob, jak určit:

Nula je sudá.
Jednotka je lichá.
Jakékoli číslo N má stejnou paritu jako N-2.

Napište rekurzivní funkci isEven podle těchto pravidel. Musí vzít číslo a vrátit booleovskou hodnotu.

Otestujte to na 50 a 75. Zkuste to dát -1. Proč se tak chová? Dá se to nějak opravit?

Otestujte to na 50 a 75. Podívejte se, jak se chová na -1. Proč? Můžeš vymyslet způsob, jak to opravit?

Console.log(isEven(50)); // → true console.log(isEven(75)); // → false console.log(isEven(-1)); // → ??

Počítáme fazole.

Číslo znaku N řetězce lze získat přidáním .charAt(N)("string".charAt(5)) k němu podobným způsobem jako získání délky řetězce s .length. Vrácenou hodnotou bude jeden znakový řetězec (například "k"). První znak řetězce má pozici 0, což znamená, že poslední znak bude mít pozici string.length - 1. Jinými slovy, řetězec dvou znaků má délku 2 a jeho pozice znaků budou 0 a 1.

Napište funkci countBs, která vezme řetězec jako argument a vrátí počet znaků "B" v řetězci.

Pak napište funkci countChar, která funguje podobně jako countBs, až na to, že potřebuje druhý parametr, znak, který budeme v řetězci hledat (místo pouhého počítání počtu znaků „B“). Chcete-li to provést, přepište funkci countBs.

Skokové příkazy a zpracování výjimek

Další kategorií operátorů jazyka JavaScript jsou operátory skoků. Jak název napovídá, tyto příkazy způsobí, že interpret JavaScriptu skočí na jiné místo v kódu programu. Příkaz break způsobí, že interpret skočí na konec smyčky nebo jiného příkazu. Příkaz continue způsobí, že interpret přeskočí zbytek těla smyčky, přeskočí zpět na začátek smyčky a spustí novou iteraci. V JavaScript je možné označit příkazy jmény, takže příkazy break a continue mohou být explicitně označeny, do kterého cyklu nebo do kterého jiného příkazu patří.

Příkaz return způsobí, že interpret skočí z volané funkce zpět do bodu, ve kterém byla volána, a vrátí hodnotu volání. Příkaz throw vyvolá výjimku a je navržen tak, aby fungoval ve spojení s příkazy try/catch/finally, které definují blok. programový kód vyřídit výjimku. Jedná se o poměrně komplikovaný druh příkazů skoku: když dojde k výjimce, interpret skočí na nejbližší uzavřený handler výjimky, který může být ve stejné funkci nebo vyšší, na návratovém zásobníku volané funkce.

Každý z těchto skokových operátorů je podrobněji popsán v následujících podkapitolách.

Instrukce štítky

Každý příkaz může být označen identifikátorem a před ním dvojtečkou:

identifikátor: instrukce

Když označíte instrukci, dáte jí název, který pak může být použit jako reference kdekoli v programu. Můžete označit jakoukoli instrukci, ale smysl má označovat pouze instrukce, které mají tělo, jako jsou smyčky a podmíněné příkazy.

Zadáním názvu smyčky ji pak lze použít v příkazech break a continue, uvnitř smyčky k opuštění smyčky nebo ke skoku na začátek smyčky do další iterace. Příkazy break a continue jsou jediné příkazy v jazyce JavaScript, které mohou obsahovat štítky – podrobněji o nich pojednáme později. Následuje příklad příkazu while s popiskem a příkazu continue používajícího toto označení:

Mainloop: while (token != null) ( // Kód programu vynechán... pokračovat v hlavní smyčce; // Přejít na další iteraci pojmenované smyčky )

Identifikátor použitý jako štítek příkazu může být jakýkoli platný identifikátor JavaScript kromě vyhrazené slovo. Názvy štítků jsou oddělené od názvů proměnných a funkcí, takže jako štítky můžete použít identifikátory, které odpovídají názvům proměnných nebo funkcí.

Názvy instrukcí jsou definovány pouze v rámci instrukcí, kterých se týkají (a samozřejmě v rámci instrukcí v nich vnořených). Vnořené instrukce nemohou být označeny stejnými identifikátory jako instrukce, které obsahují, ale dvě nezávislé instrukce mohou být označeny stejným štítkem. Označené pokyny lze znovu označit. To znamená, že jakákoli instrukce může mít více štítků.

příkaz break

Příkaz break způsobí okamžité ukončení nejvnitřnější smyčky nebo příkazu switch. Příklady použití příkazu break uvnitř příkazu switch jsme již viděli dříve. Ve smyčkách se obvykle používá k okamžitému ukončení smyčky, když je z nějakého důvodu nutné ukončit provádění smyčky.

Když je cyklus velmi složitý stav dokončení, je často snazší implementovat tyto podmínky pomocí příkazu break, než se je pokoušet vyjádřit v jediné podmíněné smyčce. Následující příklad se pokouší najít prvek pole s konkrétní hodnotou. Cyklus končí obvyklým způsobem, když je dosaženo konce pole, nebo příkazem break, jakmile je nalezena požadovaná hodnota:

Var arr = ["a","b","c","d","e"], výsledek; for (var i = 0; i

V JavaScriptu je povoleno zadat název štítku za klíčové slovo zlom (identifikátor bez dvojtečky):

break název_štítku;

Když je příkaz break použit s návěštím, skočí na konec pojmenovaného příkazu nebo ukončí jeho provádění. Pokud chybí instrukce se zadaným návěštím, pokus o použití této formy příkazu break vygeneruje chybu syntaxe. Pojmenovaný příkaz nemusí být smyčka nebo příkaz switch. Označený příkaz break může „uniknout“ z jakéhokoli obsahujícího příkazu. Může být i přiložený návod jednoduchý blok pokyny uzavřené ve složených závorkách pouze za účelem jejich označení.

Mezi klíčové slovo break a název štítku nelze vložit znak nového řádku. Je to proto, že interpret JavaScriptu automaticky vkládá chybějící středníky: pokud přerušíte řádek kódu mezi klíčové slovo break a štítek, který za ním následuje, interpret bude předpokládat, že jste mysleli jednoduchou formu tohoto operátoru bez štítku, a přidá středník .

Označený příkaz break je vyžadován pouze v případě, že chcete přerušit provádění příkazu, který není nejbližší uzavřenou smyčkou nebo příkazem switch.

pokračování prohlášení

Příkaz continue je podobný příkazu break. Místo ukončení smyčky však příkaz continue spustí novou iteraci smyčky. Syntaxe příkazu continue je stejně jednoduchá jako syntaxe příkazu break. Příkaz continue lze také použít se štítkem.

Příkaz continue, ať už neoznačený nebo označený, lze použít pouze v těle smyčky. Použití kdekoli jinde vede k chybě syntaxe. Když se provede příkaz continue, aktuální iterace smyčky se přeruší a začne další. Pro odlišné typy cykly znamenají různé věci:

    V cyklu while se znovu zkontroluje výraz zadaný na začátku cyklu, a pokud je pravdivý, tělo cyklu se provede od začátku.

    Smyčka do/while skočí na konec smyčky, kde se podmínka znovu zkontroluje před opakováním smyčky.

    Ve smyčce for se vyhodnotí inkrementační výraz a znovu se vyhodnotí testovací výraz, aby se určilo, zda má být provedena další iterace.

    Ve smyčce for/in začíná smyčka znovu s přiřazením zadaného název proměnné další nemovitost.

Všimněte si rozdílu v chování příkazu continue v cyklech while a for. Cyklus while se vrátí přímo do své podmínky a pro smyčku nejprve vyhodnotí inkrementační výraz a poté se vrátí k podmínce. Následující příklad ukazuje použití neoznačeného příkazu continue k ukončení aktuální iterace smyčky pro sudá čísla:

var součet = 0; // Vypočítejte součet lichých čísel od 0 do 10 pro (var i = 0; i

Příkaz continue, stejně jako break, lze použít ve vnořených cyklech ve formě, která obsahuje návěští, v takovém případě restartovaná smyčka nemusí nutně obsahovat příkaz continue. Stejně jako u break nejsou povoleny nové řádky mezi klíčovým slovem continue a názvem štítku.

návratový výpis

Volání funkce je výraz a jako všechny výrazy má svou hodnotu. Příkaz return uvnitř funkcí se používá k určení hodnoty vrácené funkcí. Příkaz return lze umístit pouze do těla funkce. Jeho přítomnost kdekoli jinde je syntaktická chyba. Když je proveden příkaz return, funkce vrátí hodnotu výrazu volajícímu programu. Například:

Pokud funkce nemá příkaz return, při jejím volání interpret provede instrukce v těle funkce jednu po druhé, dokud nedosáhne konce funkce, a poté vrátí řízení programu, který ji volal. V tomto případě se výraz volání vrátí jako nedefinovaný. Příkaz return je často posledním příkazem ve funkci, ale to je zcela nepovinné: funkce vrátí řízení volajícímu programu, jakmile je dosaženo příkazu return, i když po něm následují další příkazy v těle funkce.

Příkaz return lze také použít bez výrazu, v takovém případě jednoduše zruší funkci a vrátí volajícímu nedefinovaný. Například:

Funkce myFun(arr) ( // Pokud pole obsahuje záporná čísla, přerušte funkci pro (var i = 0; i

příkaz hodit

Výjimka je signál indikující výskyt nějaké výjimky nebo chyby. Vyvolání výjimky (hození) je způsob, jak signalizovat takovou chybu nebo výjimku. Chytit výjimku (chytit) znamená zvládnout, tzn. podniknout kroky nezbytné nebo vhodné pro zotavení z výjimky.

V JavaScriptu jsou výjimky vyvolány, když dojde k chybě běhu a když ji program explicitně vyvolá příkazem throw. Výjimky jsou zachyceny pomocí příkazů try/catch/finally, které jsou popsány později.

Příkaz throw má následující syntaxi:

vrhací výraz;

Výsledkem výrazu může být hodnota libovolného typu. Příkazu throw lze předat číslo představující kód chyby nebo řetězec obsahující text chybové zprávy. Interpret JavaScriptu vyvolá výjimky pomocí instance třídy chyba jednu z jeho podtříd a můžete také použít podobný přístup. Objekt Error má vlastnost název, který definuje typ chyby a vlastnost zpráva A obsahující řetězec předaný funkci konstruktoru. Následuje příklad funkce, která vyvolá objekt Error při volání s neplatným argumentem:

// Faktoriální funkce číselné funkce faktoriál(číslo) ( // Pokud vstupní argument není platná hodnota, // je vyvolána výjimka! if (číslo 1; i *= číslo, číslo--); /* tělo prázdné smyčky */ return i; ) konzole. log("5! = ", faktoriál(5)); konzole. log("-3! = ", faktoriál(-3));

Když je vyvolána výjimka, interpret JavaScript okamžitě přeruší normální provádění programu a přeskočí na nejbližší obslužnou rutinu výjimky. Obslužné rutiny výjimek používají příkaz catch konstruktu try/catch/finally, který je popsán v další části.

Pokud blok kódu, ve kterém byla vyvolána výjimka, nemá odpovídající konstrukci catch, interpret analyzuje následující venkovní jednotka programový kód a zkontroluje, zda je k němu přidružena obsluha výjimky. Toto pokračuje, dokud není nalezen handler.

Pokud je výjimka vyvolána ve funkci, která neobsahuje konstrukci try/catch/finally pro její zpracování, pak se výjimka rozšíří nahoru do kódu, který funkci zavolal. Tímto způsobem se výjimky šíří podél lexikální struktury JavaScriptové metody nahoru v zásobníku hovorů. Pokud není obslužná rutina výjimky nikdy nalezena, je výjimka považována za chybu a je nahlášena uživateli.

zkusit/chytit/konečně postavit

Konstrukce try/catch/finally implementuje mechanismus zpracování výjimek JavaScriptu. zkuste prohlášení v tomto konstruktu jednoduše definuje blok kódu, ve kterém se zpracovávají výjimky. Následuje blok try úlovek s blokem příkazů, které se mají volat, pokud kdekoli v bloku try dojde k výjimce. Za příkazem catch následuje blok Konečně A, které obsahuje kód, který provádí závěrečné operace a je zaručeno, že se spustí bez ohledu na to, co se stane v bloku try.

Blok catch i blok final jsou volitelné, ale po bloku try musí být přítomen alespoň jeden z nich. zkuste, chytněte a nakonec bloky začínají a končí složené závorky. Toto je povinná část syntaxe a nelze ji vynechat, i když je mezi nimi pouze jeden příkaz.

Následující úryvek ilustruje syntaxi a účel konstrukce try/catch/finally:

Zkuste ( // Normálně poběží tento kód hladce od začátku do konce. // Ale v určitém okamžiku v něm může // být vyvolána výjimka, buď přímo příkazem throw, nebo nepřímo // voláním metody, která vyvolá výjimku. ) catch (ex) ( // Příkazy v tomto bloku se provedou tehdy a jen tehdy, když dojde k výjimce v bloku try //. Tyto příkazy mohou používat lokální proměnnou ex, která // odkazuje na objekt Error nebo na jinou hodnotu zadanou v příkazu throw. // Tento blok může výjimku nějakým způsobem zpracovat, buď ji // ignorovat a udělat něco jiného, ​​nebo // výjimku vrátit příkazem throw. ) nakonec ( // Tento blok obsahuje příkazy, které se provádějí vždy, bez ohledu na to, // co se stalo v bloku try Jsou provedeny, pokud blok try skončil: // 1) jako obvykle, dosažení konce bloku // 2) kvůli přerušení, příkazy continue nebo return // 3) s výjimkou, kterou zpracovává v bloku catch výše // ​​4) s nezachycenou výjimkou, která se nadále // šíří do vyšších úrovní)

Všimněte si, že za klíčovým slovem catch následuje identifikátor v závorce. Tento identifikátor je podobný parametru funkce. Když je zachycena výjimka, bude tento parametr nastaven na výjimku (například objekt Error). Na rozdíl od normální proměnné existuje identifikátor spojený s příkazem catch pouze v těle bloku catch.

Následuje realističtější příklad konstrukce try/catch. Volá metodu factorial() definovanou v předchozím příkladu a pohotové metody() a alert() JavaScript na straně klienta pro uspořádání vstupu a výstupu:

Zkuste ( // Požádejte uživatele o číslo var n = Number(prompt("Zadejte kladné číslo", "")); // Vypočítejte faktoriál čísla za předpokladu, že // je vstup platný var f = faktoriál( n); // Vytisknout upozornění na výsledek(n + "! = " + f); ) catch (ex) ( // Pokud jsou data nesprávná, kontrola bude přenesena sem alert(ex); // Informujte uživatele o chyba )

Pokud uživatel zadá záporné číslo, zobrazí se varovná zpráva:

Toto je příklad konstrukce try/catch bez příkazu final. I když se konečně nepoužívá tak často jako catch, přesto je někdy užitečný. Je zaručeno, že se vykoná blok final, pokud byla provedena alespoň některá část bloku try, bez ohledu na to, jak kód v bloku try skončil. Tato funkce se obvykle používá k provádění závěrečných operací po provedení kódu v pokračování pokusu.

V normální situaci se ovládání dostane na konec bloku try a poté skočí na blok final, který provede nezbytné závěrečné operace. Pokud ovládací prvek opustí blok try v důsledku příkazu return, continue nebo break, provede se poslední blok, než je ovládací prvek přenesen jinam.

Pokud se v bloku try vyskytne výjimka a existuje vhodný blok catch, který by ji mohl zpracovat, řízení se nejprve přenese do bloku catch a poté do bloku final. Pokud neexistuje žádný blok místního zachycení, pak řízení nejprve přejde na blok konečně a pak skočí na nejbližší vnější blok zachycení, který dokáže zpracovat výjimku.

Pokud samotný blok konečně předá řízení příkazem return, continue, break nebo throw nebo voláním metody, která vyvolá výjimku, čekající přenos se zruší a provede se nový. Pokud například blok konečně vyvolá výjimku, tato výjimka nahradí všechny dříve vyvolané výjimky.

Operátor vrátit se ukončí aktuální funkci a vrátí její hodnotu.

Zdrojový kód tohoto interaktivního příkladu je uložen v úložišti GitHub. Pokud se chcete projektu zúčastnit interaktivní příklady prosím naklonujte https://github.com/mdn/interactive-examples

Syntax

return [[výraz]]; výraz Výraz, jehož hodnota bude vrácena. Pokud není zadán, vrátí se místo toho undefined.

Popis

Když je ve funkci zavolán příkaz return, její provádění se zastaví. Zadaná hodnota se vrátí na místo, kde byla funkce volána. Například následující funkce vrátí druhou mocninu svého argumentu x (kde x je číslo):

funkce square(x) ( return x * x; ) var demo = square(3); // demo hodnota bude 9

Pokud není zadána žádná návratová hodnota, vrátí se místo toho undefined.

Následující výrazy vždy ukončují provádění funkce:

vrátit se; vrátit true; vrátit false; návrat x; návrat x + y / 3;

Automatické středníky

function magic(x) ( return function calc(x) ( return x * 42 ); ) var answer = magic(); odpověď(1337); // 56154

Specifikace

Specifikace Postavení Komentář
ECMAScript 1. vydání (ECMA-262) Standard původní definice
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (6. vydání, ECMA-262)
Definice "výpisu o vrácení" v této specifikaci.
Standard
ECMAScript nejnovější koncept (ECMA-262)
Definice "výpisu o vrácení" v této specifikaci.
Návrh

Kompatibilita prohlížeče

Tabulka kompatibility na této stránce je generována ze strukturovaných dat. Pokud byste chtěli přispět k datům, podívejte se na to z https://github.com/mdn/browser-compat-data úložiště a pošlete nám žádost o stažení vašich změn.

Aktualizujte údaje o kompatibilitě na GitHubu

Počítačemobilní, pohyblivíserver
ChromeokrajFirefoxinternet ExplorerOperasafariandroid webviewChrome pro AndroidFirefox pro AndroidOpera pro AndroidSafari na iOSInternet SamsungNode.js
vrátit seChrome Plná podpora 1 okraj Plná podpora 12 Firefox Plná podpora 1 TJ Plná podpora 3 Opera Plná podpora Anosafari Plná podpora Anowebview android Plná podpora 1 Chrome Android Plná podpora 18 Firefox pro Android Plná podpora 4 OperaAndroid Plná podpora AnoSafari iOS Plná podpora AnoSamsung Internet Android Plná podpora 1.0 nodejs Plná podpora Ano