Funkcie sú jedným z najdôležitejších stavebných kameňov kódu v JavaScripte.

Funkcie pozostávajú zo sady príkazov a zvyčajne vykonávajú jednu konkrétnu úlohu (napríklad sčítanie čísel, výpočet odmocniny atď.).

Kód umiestnený vo funkcii sa vykoná až po explicitnom volaní tejto funkcie.

Deklarácia funkcie

1.Syntax:

//Funkcia deklarácie funkcie FunctionName(var1, var2)( Kód funkcie ) //Volanie funkcie FunctionName(var1,var2);

2. Syntax:

//Deklarácia funkcie var functionname=function(var1, var2)(Kód funkcie) //Volanie funkcie functionname(var1,var2);

názov funkcie určuje názov funkcie. Každá funkcia na stránke musí mať jedinečný názov. Názov funkcie musí byť zadaný latinkou a nesmie začínať číslicami.

za1 a za2 sú premenné alebo hodnoty, ktoré možno odovzdať do funkcie. Každej funkcii je možné odovzdať neobmedzený počet premenných.

Poznámka: aj keď funkcii neodovzdáte žiadne premenné, nezabudnite za názov funkcie vložiť zátvorky „()“.

Poznámka: Názvy funkcií v JavaScripte rozlišujú veľké a malé písmená.

Príklad funkcie JavaScript

Funkcia messageWrite() v príklade nižšie sa spustí až po kliknutí na tlačidlo.

Poznámka: tento príklad používa udalosť onclick. JavaScript udalosti bude podrobne diskutované neskôr v tomto návode.

Odovzdávanie premenných funkciám

Funkciám môžete odovzdať neobmedzený počet premenných.

Poznámka: všetky manipulácie s premennými vnútri funkcií sa v skutočnosti nevykonávajú na samotných premenných, ale na ich kópii, takže obsah samotných premenných sa v dôsledku vykonávania funkcií nemení.

/* Definujte funkciu, ktorá pridá 10 k odovzdanej premennej a vypíše výsledok na stránku */ function plus(a)( a=a+10; document.write("Výstup funkcie: " + a+"
"); ) var a=25; document.write("Hodnota premennej pred volaním funkcie: "+a+"
"); // Zavolajte funkciu, ktorá jej odovzdá premennú plus(a); document.write("Hodnota premennej po volaní funkcie: "+a+"
");

Rýchle zobrazenie

Ak chcete získať prístup ku globálnej premennej z funkcie a nie z jej kópie, použite window.name_variable_name.

Funkcia plus(a)( okno.a=a+10; ) var a=25; document.write("Hodnota premennej pred volaním funkcie: "+a+"
"); plus(a); document.write("Hodnota premennej po volaní funkcie: "+a+"
");

Rýchle zobrazenie

návratový príkaz

S príkazom vrátiť Môžete vrátiť hodnoty z funkcií.

Rýchle zobrazenie

Vstavané funkcie

Okrem užívateľsky definovaných funkcií v JavaScripte existujú aj vstavané funkcie.

Napríklad vstavaná funkcia isFinite umožňuje skontrolovať, či odovzdaná hodnota je platné číslo.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90,33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("Toto je reťazec")+"
");

Rýchle zobrazenie

Poznámka: úplný zoznam vstavané funkcie JavaScriptu nájdete v našom .

Lokálne a globálne premenné

Volajú sa premenné vytvorené vo vnútri funkcií lokálne premenné. K takýmto premenným máte prístup iba v rámci funkcií, v ktorých boli definované.

Po vykonaní kódu funkcie sa takéto premenné zničia. To znamená, že premenné s rovnakým názvom môžu byť definované v rôznych funkciách.

Volajú sa premenné, ktoré sú vytvorené mimo kódu funkcie globálne premenné k takýmto premenným je možné pristupovať odkiaľkoľvek v kóde.

Ak vo funkcii deklarujete premennú bez var, stane sa tiež globálnou.

Globálne premenné sa zničia iba pri zatvorení stránky.

Rýchle zobrazenie

Poznámka: keď sa zobrazí, var2 bude mať hodnotu null, pretože func1 funguje na lokálnej "verzii" var2.

Používanie anonymných funkcií

Volajú sa funkcie, ktoré pri deklarácii neobsahujú názov anonymný.

Anonymné funkcie sú v podstate deklarované nie pre ich následné volanie z kódu ako bežné funkcie, ale pre prechod do iných funkcií ako parameter.

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

Rýchle zobrazenie

Urob si sám

Cvičenie 1. Opravte chyby v kóde nižšie:

Cvičenie 1

Opravte chybu v kóde.

Úloha 2.

  1. Reprodukujte kód funkcií 1-3 preskúmaním ich správania pri odovzdávaní rôznych parametrov.
  2. Určte kľúčové slovo interakciou s funkciou 4.

Úloha 2

//Zavolajte prvú tajnú funkciu document.write(secfunc1(4,12) + "
"); // Volanie druhej tajnej funkcie document.write(secfunc2(100,10) + "
"); //Zavolajte tretiu tajnú funkciu secfunc3(23,10); document.write("
"); // Volanie štvrtej tajnej funkcie secfunc4("p");

Ak chcete používať systém komentárov Disqus, povoľte JavaScript.

Ľudia si myslia, že informatika je umenie pre géniov. V skutočnosti je opak pravdou – len veľa ľudí robí veci, ktoré stoja na sebe, akoby tvorili stenu z malých kamienkov.

Donald Knuth

Volania funkcií, ako napríklad upozornenie, ste už videli. Funkcie sú chlebom a maslom programovania v JavaScripte. Myšlienka zabaliť časť programu a nazvať ju ako premennú je veľmi populárna. Je to nástroj na štruktúrovanie veľkých programov, redukciu opakovania, priraďovanie názvov podprogramom a izoláciu podprogramov od seba.

Najzrejmejším použitím funkcií je vytvorenie nového slovníka. Vymýšľať slová pre obyčajnú ľudskú prózu je zlá forma. V programovacom jazyku je to nevyhnutné.

Priemerný dospelý hovoriaci po rusky pozná asi 10 000 slov. Vzácny programovací jazyk obsahuje 10 000 vstavaných príkazov. A slovná zásoba programovacieho jazyka je jasnejšie definovaná, takže je menej flexibilná ako ľudský. Preto k nemu väčšinou musíme pridať vlastné slová, aby sme sa vyhli zbytočnému opakovaniu.

Definícia funkcie

Definícia funkcie je normálna definícia premennej, kde hodnota, ktorú premenná dostáva, je funkcia. Napríklad nasledujúci kód definuje premenný štvorec, ktorý odkazuje na funkciu, ktorá vypočítava druhú mocninu daného čísla:

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

Funkciu vytvára výraz začínajúci kľúčovým slovom function. Funkcie majú množinu parametrov (v tomto prípade iba x) a telo obsahujúce inštrukcie, ktoré sa majú vykonať pri volaní funkcie. Telo funkcie je vždy uzavreté v zložených zátvorkách, aj keď pozostáva z jedného príkazu.

Funkcia môže mať niekoľko parametrov alebo žiadny. V nasledujúcom príklade makeNoise nemá zoznam parametrov, zatiaľ čo napájanie má dva:

Var makeNoise = function() ( console.log("Fuck!"); ); Robit hluk(); // → Sakra! var mocnina = funkcia (základ, exponent) ( var výsledok = 1; pre (počet var = 0; počet< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Niektoré funkcie vracajú hodnotu, napríklad mocnina a štvorec, iné nie, napríklad makeNoise, čo má len vedľajší účinok. Príkaz return definuje hodnotu vrátenú funkciou. Keď spracovanie programu dosiahne túto inštrukciu, okamžite opustí funkciu a vráti túto hodnotu na miesto v kóde, odkiaľ bola funkcia volaná. return bez výrazu vracia undefined .

Parametre a rozsah

Parametre funkcie sú rovnaké ako premenné, ale ich počiatočné hodnoty sa nastavujú pri volaní funkcie a nie v jej kóde.

Dôležitou vlastnosťou funkcií je, že premenné vytvorené v rámci funkcie (vrátane parametrov) sú v rámci tejto funkcie lokálne. To znamená, že v mocenskom príklade sa premenná výsledok vytvorí pri každom volaní funkcie a tieto jej samostatné inkarnácie spolu nijako nesúvisia.

Táto lokalita premenných sa vzťahuje len na parametre a premenné vytvorené vo funkciách. Premenné nastavené mimo akejkoľvek funkcie sa nazývajú globálne premenné, pretože sú viditeľné v celom programe. K takýmto premenným môžete pristupovať aj v rámci funkcie, pokiaľ ste nedeklarovali lokálnu premennú s rovnakým názvom.

Ilustruje to nasledujúci kód. Definuje a volá dve funkcie, ktoré priraďujú hodnotu x. Prvý ju deklaruje ako lokálnu, čím zmení iba lokálnu premennú. Druhý nedeklaruje, takže práca s x vo vnútri funkcie odkazuje na globálnu premennú x, ktorá bola nastavená na začiatku príkladu.

var x = "vonku"; var f1 = funkcia() ( var x = "vo vnútri f1"; ); f1(); konzolový denník (x); // → mimo var f2 = function() ( x = "vo vnútri f2"; ); f2(); konzolový denník (x); // → vnútri f2

Toto správanie pomáha predchádzať náhodnej interakcii medzi funkciami. Ak by sa kdekoľvek v programe použili všetky premenné, bolo by veľmi ťažké zabezpečiť, aby sa jedna premenná nepoužívala na rôzne účely. A ak by ste premennú znova použili, narazili by ste na podivné efekty, keď kód tretej strany zasahoval do hodnôt vašej premennej. Spracovaním funkčných lokálnych premenných tak, aby existovali iba v rámci funkcie, jazyk umožňuje pracovať s funkciami, ako keby to boli samostatné malé vesmíry, čo vám umožňuje nestarať sa o celý kód ako celok.

Vnorené rozsahy

JavaScript nerozlišuje len medzi globálnymi a lokálnymi premennými. Funkcie možno definovať v rámci funkcií, výsledkom čoho je niekoľko úrovní lokality.

Napríklad nasledujúca dosť nezmyselná funkcia obsahuje vo vnútri ďalšie dve:

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()); // → ___/""""\______/"\_

Ploché a horské funkcie vidia výslednú premennú, pretože sú vo funkcii, v ktorej je definovaná. Nemôžu však vidieť navzájom početné premenné, pretože premenné jednej funkcie sú mimo rozsahu druhej. A prostredie mimo funkcie krajiny nevidí žiadnu z premenných definovaných vo vnútri tejto funkcie.

Stručne povedané, v každom lokálnom rozsahu môžete vidieť všetky rozsahy, ktoré ho obsahujú. Množina premenných dostupných vo funkcii je určená miestom, kde je táto funkcia deklarovaná v programe. Všetky premenné z blokov obklopujúcich definíciu funkcie sú viditeľné – vrátane tých, ktoré sú definované na najvyššej úrovni v hlavnom programe. Tento prístup k rozsahom sa nazýva lexikálny.

Ľudia, ktorí študovali iné programovacie jazyky, si môžu myslieť, že každý blok uzavretý v zložených zátvorkách vytvára svoje vlastné lokálne prostredie. Ale v JavaScripte vytvárajú rozsah iba funkcie. Môžete použiť samostatné bloky:

var nieco = 1; ( var niečo = 2; // Urobte niečo s premennou niečo... ) // Ukončite blok...

Ale niečo vo vnútri bloku je rovnaká premenná ako vonku. Aj keď sú takéto bloky povolené, má zmysel ich používať iba pre príkazy if a cykly.

Ak sa vám to zdá zvláštne, zdá sa to nielen vám. JavaScript 1.7 zaviedol kľúčové slovo let, ktoré funguje ako var, ale vytvára premenné, ktoré sú lokálne pre akýkoľvek daný blok, nielen pre funkciu.

Funguje ako hodnoty

Názvy funkcií sa zvyčajne používajú ako názov časti programu. Takáto premenná je raz nastavená a nemení sa. Je teda ľahké pomýliť si funkciu s jej názvom.

Ale to sú dve rozdielne veci. Volanie funkcie je možné použiť ako jednoduchú premennú – možno ich napríklad použiť v akomkoľvek výraze. Je možné uložiť volanie funkcie do novej premennej, odovzdať ho ako parameter inej funkcii atď. Tiež premenná, ktorá ukladá volanie funkcie, zostáva obyčajnou premennou a jej hodnotu možno zmeniť:

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

V kapitole 5 budeme diskutovať o úžasných veciach, ktoré sa dajú urobiť odovzdaním volaní funkcií iným funkciám.

Deklarácia funkcie

Existuje kratšia verzia výrazu „var square = funkcia…“. Kľúčové slovo funkcie možno použiť na začiatku príkazu:

funkcia square(x) ( return x * x; )

Toto je deklarácia funkcie. Príkaz definuje premennú štvorec a priraďuje jej danú funkciu. Zatiaľ je všetko ok. Takáto definícia má len jedno úskalie.

Console.log("Budúcnosť hovorí:", future()); function future() ( return "STÁLE nemáme žiadne lietajúce autá."; )

Tento kód funguje, aj keď je funkcia deklarovaná pod kódom, ktorý ju používa. Je to preto, že deklarácie funkcií nie sú súčasťou bežného vykonávania programov zhora nadol. „Pohybujú sa“ na vrchol svojho rozsahu a môžu byť volané akýmkoľvek kódom v tomto rozsahu. To je niekedy výhodné, pretože kód môžete napísať v poradí, ktoré dáva najväčší zmysel, bez toho, aby ste sa museli obávať, že budete musieť definovať všetky funkcie vyššie, kde sa používajú.

Čo sa však stane, ak umiestnime deklaráciu funkcie do podmieneného bloku alebo slučky? Nemusíte to robiť. Historicky rôzne platformy na spúšťanie JavaScriptu riešili takéto prípady odlišne a súčasný jazykový štandard to zakazuje. Ak chcete, aby vaše programy bežali konzistentne, použite deklarácie funkcií iba v rámci iných funkcií alebo hlavného programu.

Príklad funkcie() ( funkcia a() () // Norma if (niečo) ( funkcia b() () // Ay-yy-yy! ) )

zásobník hovorov
Je užitočné pozrieť sa bližšie na to, ako príkaz na vykonanie funguje s funkciami. Tu je jednoduchý program s niekoľkými volaniami funkcií:

Funkcia pozdrav(kto) ( console.log("Ahoj, " + kto); ) pozdrav("Semyon"); console.log("Pokeda");

Spracuje sa asi takto: volanie pozdravu spôsobí skok na začiatok funkcie. Zavolá vstavanú funkciu console.log, ktorá prevezme kontrolu, urobí svoju vec a vráti kontrolu. Potom sa dostane na koniec pozdravu a vráti sa na miesto, z ktorého bolo volané. Ďalší riadok opäť volá console.log.

Schematicky to možno znázorniť takto:

Top pozdrav console.log pozdrav top console.log top

Pretože funkcia sa musí vrátiť tam, odkiaľ bola volaná, počítač si musí zapamätať kontext, z ktorého bola funkcia volaná. V jednom prípade by sa mal console.log zmeniť späť na pozdrav. V inom sa vráti na koniec programu.

Miesto, kde si počítač pamätá kontext, sa nazýva zásobník. Pri každom volaní funkcie sa aktuálny kontext presunie na vrch zásobníka. Keď sa funkcia vráti, vytiahne horný kontext zo zásobníka a použije ho na pokračovanie.

Zásobník vyžaduje miesto v pamäti. Keď sa zásobník príliš zväčší, počítač prestane vykonávať prácu a vydá niečo ako „pretečenie zásobníka“ alebo „príliš veľa rekurzie“. Dokazuje to nasledujúci kód – kladie počítaču veľmi zložitú otázku, ktorá vedie k nekonečným skokom medzi dvoma funkciami. Presnejšie povedané, išlo by o nekonečné skoky, ak by mal počítač nekonečný zásobník. V skutočnosti zásobník pretečie.

Funkcia chicken() ( return egg(); ) function egg() ( return chicken(); ) console.log(chicken() + "prišlo prvé."); // → ??

Voliteľné argumenty
Nasledujúci kód je úplne legálny a funguje bez problémov:

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

Oficiálne má funkcia jeden argument. Keď ju však takto vyzvú, nesťažuje sa. Ignoruje zvyšok argumentov a zobrazí "Ahoj".

JavaScript je veľmi zhovievavý, pokiaľ ide o počet argumentov odovzdaných funkcii. Ak prejdete príliš veľa, ďalšie budú ignorované. Príliš málo – chýbajúcim bude priradená hodnota nedefinovaná.

Nevýhodou tohto prístupu je, že je možné – a dokonca pravdepodobné – odovzdať funkcii nesprávny počet argumentov a nikto sa vám na to nebude sťažovať.

Výhodou je, že môžete vytvárať funkcie, ktoré majú voliteľné argumenty. Napríklad v ďalšej verzii mocninnej funkcie ju možno volať s dvomi aj s jedným argumentom – v druhom prípade bude exponent rovný dvom a funkcia funguje ako štvorec.

Mocnina funkcie (základ, exponent) ( ak (exponent == nedefinovaný) exponent = 2; výsledok var = 1; pre (počet var = 0; počet< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

V ďalšej kapitole uvidíme, ako vám telo funkcie môže povedať presný počet argumentov, ktoré jej boli odovzdané. To je užitočné, pretože umožňuje vytvoriť funkciu, ktorá má ľubovoľný počet argumentov. Napríklad console.log používa túto vlastnosť a vypíše všetky argumenty, ktoré sú mu odovzdané:

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

Uzávery

Schopnosť používať volania funkcií ako premenné v spojení so skutočnosťou, že lokálne premenné sa znova vytvárajú pri každom volaní funkcie, nás privádza k zaujímavému bodu. Čo sa stane s lokálnymi premennými, keď funkcia zlyhá?

Nasledujúci príklad ilustruje tento problém. Deklaruje funkciu wrapValue, ktorá vytvorí lokálnu premennú. Potom vráti funkciu, ktorá prečíta túto lokálnu premennú a vráti jej hodnotu.

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

Toto platí a funguje ako má – prístup k premennej zostáva zachovaný. Okrem toho môže súčasne existovať viacero inštancií tej istej premennej, čo ďalej potvrdzuje skutočnosť, že pri každom volaní funkcie sa znova vytvárajú lokálne premenné.

Táto schopnosť pracovať s odkazom na nejakú inštanciu lokálnej premennej sa nazýva uzáver. Funkcia, ktorá uzatvára lokálne premenné, sa nazýva uzatváracia funkcia. Nielenže vás zbaví starostí s premenlivou životnosťou, ale tiež vám umožní kreatívne využívať funkcie.

S miernou zmenou zmeníme náš príklad na funkciu, ktorá násobí čísla ľubovoľným daným číslom.

Násobiteľ funkcie (faktor) ( návratová funkcia (číslo) ( návratové číslo * faktor; ); ) var dvakrát = multiplikátor(2); console.log(dvakrát(5)); // → 10

Samostatná premenná ako localVariable z príkladu wrapValue už nie je potrebná. Pretože parameter je sám o sebe lokálna premenná.

Začať takto rozmýšľať si vyžaduje prax. Dobrou verziou mentálneho modelu je predstaviť si, že funkcia zmrazí kód vo svojom tele a zabalí ho do obalu. Keď uvidíte funkciu return(...) (...), predstavte si ju ako ovládací panel pre časť kódu, ktorá je zmrazená na neskoršie použitie.

V našom príklade multiplikátor vráti zmrazený kus kódu, ktorý uložíme do premennej double. Posledný riadok volá funkciu obsiahnutú v premennej, ktorá aktivuje uložený kód (návratové číslo * faktor;). Stále má prístup k premennej faktora, ktorá bola definovaná pri volaní multiplikátora, a má tiež prístup k argumentu odovzdanému počas rozmrazovania (5) ako číselnému parametru.

rekurzia

Funkcia sa môže volať sama, ak sa stará o to, aby nepretekala zásobník. Takáto funkcia sa nazýva rekurzívna. Tu je príklad alternatívnej implementácie umocňovania:

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

Matematici takto definujú umocňovanie a možno to vystihuje tento koncept elegantnejšie ako cyklus. Funkcia sa mnohokrát volá s rôznymi argumentmi, aby sa dosiahlo viacnásobné násobenie.

Táto implementácia má však problém – v bežnom prostredí JavaScriptu je 10x pomalšia ako verzia so slučkou. Slučovanie je lacnejšie ako volanie funkcie.

Dilema rýchlosť verzus elegancia je celkom zaujímavá. Medzi ľudskou pohodlnosťou a pohodlnosťou strojov je určitá priepasť. Akýkoľvek program možno urýchliť tým, že bude väčší a zložitejší. Od programátora sa vyžaduje, aby našiel správnu rovnováhu.

V prípade prvého umocnenia je neelegantná slučka celkom jednoduchá a priamočiara. Nemá zmysel ho nahrádzať rekurziou. Často však programy pracujú s tak zložitými konceptmi, že človek chce znížiť efektivitu zvýšením čitateľnosti.

Základné pravidlo, ktoré sa už mnohokrát opakovalo a s ktorým úplne súhlasím – netrápte sa o výkon, kým si nebudete istí, že sa program spomalí. Ak áno, nájdite diely, ktoré vydržia najdlhšie a vymeňte eleganciu za efektívnosť.

Samozrejme, nemali by sme hneď úplne ignorovať výkon. V mnohých prípadoch, podobne ako pri umocňovaní, z elegantných riešení veľa jednoduchosti nedostaneme. Niekedy skúsený programátor hneď vidí, že jednoduchý prístup nikdy nebude dostatočne rýchly.

Uvádzam to, pretože príliš veľa začínajúcich programátorov lipne na efektivite aj v malých veciach. Výsledok je väčší, zložitejší a často nie bez chýb. Takéto programy sa píšu dlhšie a často nefungujú oveľa rýchlejšie.

Ale rekurzia nie je vždy len menej efektívnou alternatívou k slučkám. Niektoré problémy sa dajú ľahšie vyriešiť rekurziou. Najčastejšie ide o prechod niekoľkých vetiev stromu, z ktorých každá sa môže vetviť.

Tu je hádanka pre vás: môžete získať nekonečný počet čísel, počnúc číslom 1 a potom buď sčítaním 5, alebo vynásobením 3. Ako napíšeme funkciu, ktorá sa pri zadaní čísla snaží nájsť postupnosť takýchto sčítania a násobenia, ktoré vedú k danému číslu? Napríklad číslo 13 možno získať tak, že najprv vynásobíte 1 3 a potom dvakrát pridáte 5. A číslo 15 je vo všeobecnosti nemožné takto získať.

Rekurzívne riešenie:

Funkcia findSolution(target) ( funkcia find(start, history) ( if (start == target) return history; else if (start > target) return null; else return find (start + 5, "(" + history + " + 5)") || find(začiatok * 3, "(" + história + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

Tento príklad nemusí nevyhnutne nájsť najkratšie riešenie - vyhovuje každému. Neočakávam, že okamžite pochopíte, ako program funguje. Poďme však k podstate tohto skvelého cvičenia rekurzívneho myslenia.

Hľadanie vnútornej funkcie je rekurzívne. Vyžaduje si to dva argumenty – aktuálne číslo a reťazec, ktorý obsahuje záznam o tom, ako sme k tomuto číslu dospeli. A vráti buď reťazec zobrazujúci našu postupnosť krokov, alebo hodnotu null.

Na tento účel funkcia vykoná jednu z troch akcií. Ak sa dané číslo rovná cieľu, súčasná história je len spôsob, ako ho dosiahnuť, a preto sa vracia. Ak dané číslo viac účelu, nemá zmysel pokračovať v množení a pridávaní, lebo takto to bude len pribúdať. A ak sme ešte nedosiahli cieľ, funkcia skúša obe možné cesty od daného čísla. Privoláva sa dvakrát, raz s každým zo spôsobov. Ak prvé volanie nevráti hodnotu null, vráti sa. V opačnom prípade sa vráti druhý.

Aby sme lepšie pochopili, ako funkcia dosahuje požadovaný efekt, pozrime sa na jej volania, ktoré sa vyskytujú pri hľadaní riešenia pre číslo 13.

Nájsť (1, "1") nájsť (6, "(1 + 5)") nájsť (11, "((1 + 5) + 5)") nájsť (16, "((1 + 5) + 5 ) + 5)") príliš veľký nález(33, "(((1 + 5) + 5) * 3)") príliš veľký nález(18, "(1 + 5) * 3)") príliš veľký nález( 3, "(1 * 3)") nájsť (8, "(1 * 3) + 5)") nájsť (13, "(((1 * 3) + 5) + 5)") nájsť!

Odsadenie zobrazuje hĺbku zásobníka hovorov. Prvýkrát sa funkcia find zavolá dvakrát, aby skontrolovala riešenia začínajúce (1 + 5) a (1 * 3). Prvý hovor hľadá riešenie začínajúce na (1 + 5) a používa rekurziu na kontrolu všetkých riešení, ktoré dávajú číslo menšie alebo rovné požadovanému číslu. Nenájde a vráti hodnotu null. Potom operátor || a skočí na volanie funkcie, ktorá skúma možnosť (1 * 3). Tu máme šťastie, pretože v treťom rekurzívnom volaní dostaneme 13. Toto volanie vráti reťazec a každý z || prejde tento reťazec vyššie pozdĺž cesty, čím vráti riešenie ako výsledok.

Grow Functions

Existujú dva viac-menej prirodzené spôsoby zavádzania funkcií do programu.

Najprv napíšete podobný kód viackrát. Tomuto sa treba vyhnúť – viac kódu znamená viac priestoru pre chyby a viac materiálu na čítanie pre tých, ktorí sa snažia program pochopiť. Takže vezmeme opakujúcu sa funkcionalitu, prispôsobíme ju dobré meno a vložte ho do funkcie.

Druhým spôsobom je, že objavíte potrebu nejakej novej funkcionality, ktorá si zaslúži umiestnenie v samostatnej funkcii. Začnete názvom funkcie a potom napíšete jej telo. Môžete dokonca začať napísaním kódu, ktorý používa funkciu, ešte pred definovaním samotnej funkcie.

To, aké ťažké je pre vás pomenovať funkciu, ukazuje, ako dobre rozumiete jej funkciám. Vezmime si príklad. Musíme napísať program, ktorý vypíše dve čísla, počet kráv a sliepok na farme, za ktorými nasledujú slová „kravy“ a „kurčatá“. K číslam vpredu musíte pridať nuly, aby každé obsadilo presne tri pozície.

007 Kravy 011 Sliepky

Je zrejmé, že potrebujeme funkciu s dvoma argumentmi. Začnime kódovať.
// funkcia printFarmInventory printFarmInventory(kravy, kurčatá) ( var cowString = String(kravy); 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);

Ak k reťazcu pridáme .length, dostaneme jeho dĺžku. Ukázalo sa, že cykly while pridávajú k číslam úvodné nuly, kým nezískajú reťazec 3 znakov.

Pripravený! Ale akonáhle sa chystáme poslať kód farmárovi (samozrejme spolu s poriadnou kontrolou), zavolá a povie nám, že má na farme ošípané a mohli by sme pridať výstup o počte ošípaných do programu?

Samozrejme je to možné. Ale keď začneme kopírovať a vkladať kód z týchto štyroch riadkov, uvedomíme si, že sa musíme zastaviť a zamyslieť sa. Musí existovať lepší spôsob. Snažíme sa vylepšiť program:

// výstup funkcie ZeroPaddedWithLabel printZeroPaddedWithLabel(číslo, označenie) ( 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);

Tvorba! Ale názov printZeroPaddedWithLabel je trochu zvláštny. Spája tri veci – výstup, nulovú výplň a štítok – do jednej funkcie. Namiesto toho, aby sme celý opakujúci sa fragment naplnili do funkcie, vyzdvihnime jeden koncept:

// pridanie funkcie Nuly zeroPad(číslo, šírka) ( 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);

Funkcia s pekným, popisným názvom zeroPad uľahčuje pochopenie kódu. A dá sa použiť v mnohých situáciách, nielen v našom prípade. Napríklad na zobrazenie formátovaných tabuliek s číslami.

Aké inteligentné a všestranné by mali byť funkcie? Môžeme písať ako najjednoduchšia funkcia, ktorý doplní číslo nulami až do troch pozícií, a efektná univerzálna funkcia formátovania čísel, ktorá podporuje zlomky, záporné čísla, zarovnanie bodov, doplnok rôzne postavy, atď.

Dobrým pravidlom je pridať iba funkcie, ktoré určite potrebujete. Niekedy je lákavé vytvoriť všeobecné rámce pre každú malú potrebu. Odolajte mu. Nikdy nedokončíte prácu, ale len napíšte kopu kódu, ktorý nikto nepoužije.

Funkcie a vedľajšie účinky

Funkcie možno zhruba rozdeliť na tie, ktoré sa volajú kvôli ich vedľajším účinkom, a tie, ktoré sa volajú, aby získali nejakú hodnotu. Samozrejme je tiež možné tieto vlastnosti kombinovať v jednej funkcii.

Prvá pomocná funkcia v príklade farmy, printZeroPaddedWithLabel, sa volá kvôli vedľajšiemu efektu tlače reťazca. Druhý, zeroPad, kvôli návratovej hodnote. A nie je náhoda, že druhá funkcia príde vhod častejšie ako prvá. Funkcie, ktoré vracajú hodnoty, sa ľahšie navzájom kombinujú ako funkcie, ktoré vytvárajú vedľajšie účinky.

Čistá funkcia je špeciálny druh funkcie vracajúcej hodnotu, ktorá nielenže nemá žiadne vedľajšie účinky, ale nezávisí ani od vedľajších účinkov zvyšku kódu – napríklad nepracuje s globálnymi premennými, ktoré je možné náhodne zmeniť. niekde inde. Čistá funkcia, keď je volaná s rovnakými argumentmi, vráti rovnaký výsledok (a nerobí nič iné) - čo je celkom pekné. Je ľahké s ňou pracovať. Volanie takejto funkcie môže byť mentálne nahradené výsledkom jej práce, bez zmeny významu kódu. Keď chcete takúto funkciu otestovať, môžete ju jednoducho zavolať a byť si istí, že ak funguje v tomto kontexte, bude fungovať v akomkoľvek. Nie tak čisté funkcie môžu vrátiť rôzne výsledky v závislosti od mnohých faktorov a majú vedľajšie účinky, ktoré sa ťažko testujú a zohľadňujú.

Netreba sa však hanbiť písať funkcie, ktoré nie sú celkom čisté, alebo začať od takýchto funkcií posvätné čistenie kódu. Vedľajšie účinky sú často užitočné. Nedá sa písať čistá verzia console.log a táto funkcia je celkom užitočná. Niektoré operácie sa dajú ľahšie vyjadriť pomocou vedľajších účinkov.

Výsledok

Táto kapitola vám ukázala, ako písať svoje vlastné funkcie. Keď sa kľúčové slovo funkcie použije ako výraz, vráti ukazovateľ na volanie funkcie. Pri použití ako príkaz môžete premennú deklarovať tak, že jej priradíte volanie funkcie.

Kľúčom k pochopeniu funkcií sú lokálne rozsahy. Parametre a premenné deklarované vo vnútri funkcie sú pre ňu lokálne, znovu sa vytvárajú pri každom jej volaní a zvonku nie sú viditeľné. Funkcie deklarované v inej funkcii majú prístup k jej rozsahu.

Je veľmi užitočné rozdeliť rôzne úlohy vykonávané programom do funkcií. Nemusíte sa opakovať, funkcie robia kód čitateľnejším tým, že ho rozdeľujú na sémantické časti, rovnako ako kapitoly a časti knihy pomáhajú organizovať obyčajný text.

Cvičenia

Minimum
V predchádzajúcej kapitole bola spomenutá funkcia Math.min, ktorá vracia najmenší zo svojich argumentov. Teraz môžeme takúto funkciu napísať sami. Napíšte funkciu min, ktorá vezme dva argumenty a vráti minimum z nich.

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

rekurzia
Videli sme, že operátor % (zvyšok) možno použiť na určenie, či je číslo párne (% 2). Tu je ďalší spôsob, ako určiť:

Nula je párna.
Jednotka je nepárna.
Akékoľvek číslo N má rovnakú paritu ako N-2.

Napíšte rekurzívnu funkciu isEven podľa týchto pravidiel. Musí vziať číslo a vrátiť boolovskú hodnotu.

Otestujte to na 50 a 75. Skúste dať -1. Prečo sa takto správa? Dá sa to nejako opraviť?

Otestujte to na 50 a 75. Pozrite sa, ako sa správa na -1. prečo? Môžeš premýšľate o spôsobe, ako to opraviť?

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

Počítame fazuľu.

Číslo znaku N v reťazci možno získať pridaním .charAt(N)("string".charAt(5)) k nemu podobným spôsobom ako získať dĺžku reťazca s .dĺžkou. Návratová hodnota bude reťazec jedného znaku (napríklad "k"). Prvý znak reťazca má pozíciu 0, čo znamená, že posledný znak bude mať pozíciu string.length - 1. Inými slovami, dvojznakový reťazec má dĺžku 2 a jeho pozície znakov budú 0 a 1.

Napíšte funkciu countBs, ktorá vezme reťazec ako argument a vráti počet znakov "B" v reťazci.

Potom napíšte funkciu countChar, ktorá funguje trochu ako countBs, až na to, že potrebuje druhý parameter, znak, ktorý budeme hľadať v reťazci (namiesto toho, aby sme len počítali počet znakov „B“). Ak to chcete urobiť, prepíšte funkciu countBs.

Skokové príkazy a spracovanie výnimiek

Ďalšou kategóriou operátorov jazyka JavaScript sú operátory skokov. Ako už názov napovedá, tieto príkazy spôsobujú, že interpret JavaScriptu preskočí na iné miesto v programovom kóde. Príkaz break spôsobí, že interpret preskočí na koniec cyklu alebo iného príkazu. Príkaz continue spôsobí, že tlmočník preskočí zvyšok tela cyklu, preskočí späť na začiatok cyklu a spustí novú iteráciu. AT JavaScript je možné označiť príkazy menami, takže príkazy break a continue môžu byť explicitne označené, do ktorého cyklu alebo do ktorého iného príkazu patria.

Príkaz return spôsobí, že interpret preskočí z volanej funkcie späť do bodu, v ktorom bola volaná, a vráti hodnotu volania. Príkaz throw vyvolá výnimku a je navrhnutý tak, aby fungoval v spojení s príkazmi try/catch/finally, ktoré definujú blok. programový kód zvládnuť výnimku. Toto je pomerne komplikovaný druh príkazov skoku: keď sa vyskytne výnimka, tlmočník preskočí na najbližší obslužný program výnimky, ktorý môže byť v rovnakej funkcii alebo vyššej, na návratovom zásobníku volanej funkcie.

Každý z týchto skokových operátorov je podrobnejšie popísaný v nasledujúcich podkapitolách.

Nálepky s pokynmi

Každý príkaz môže byť označený identifikátorom a dvojbodkou pred ním:

identifikátor: pokyn

Keď označíte inštrukciu, dáte jej názov, ktorý potom možno použiť ako referenciu kdekoľvek v programe. Môžete označiť akúkoľvek inštrukciu, ale zmysel má označovať len inštrukcie, ktoré majú telo, ako sú cykly a podmienené príkazy.

Zadaním názvu cyklu ho potom možno použiť v príkazoch break a continue, vo vnútri cyklu na výstup z neho alebo na skok na začiatok cyklu do ďalšej iterácie. Príkazy break a continue sú jediné príkazy v jazyku JavaScript, ktoré môžu obsahovať označenia – podrobnejšie sa o nich porozprávame neskôr. Nasleduje príklad príkazu while s označením a príkazu continue s týmto označením:

Hlavná slučka: while (token != null) ( // Kód programu vynechaný... pokračovať v hlavnej slučke; // Prejsť na ďalšiu iteráciu pomenovanej slučky )

Identifikátor použitý ako označenie príkazu môže byť akýkoľvek platný identifikátor JavaScript okrem vyhradené slovo. Názvy štítkov sú oddelené od názvov premenných a funkcií, takže ako štítky môžete použiť identifikátory, ktoré sa zhodujú s názvami premenných alebo funkcií.

Označenia inštrukcií sú definované iba v rámci inštrukcií, na ktoré sa vzťahujú (a samozrejme v rámci inštrukcií v nich vnorených). Vnorené pokyny nemôžu byť označené rovnakými identifikátormi, aké obsahujú pokyny, ale môžu byť označené rovnakým štítkom dva nezávislé pokyny. Označené pokyny je možné znova označiť. To znamená, že každá inštrukcia môže mať viacero označení.

vyhlásenie o prerušení

Príkaz break spôsobí okamžité ukončenie najvnútornejšej slučky alebo príkazu switch. Príklady použitia príkazu break vo vnútri príkazu switch sme už videli skôr. V slučkách sa zvyčajne používa na okamžité opustenie slučky, keď je z nejakého dôvodu potrebné ukončiť vykonávanie slučky.

Keď je cyklus veľmi zložitý stav dokončenia, je často jednoduchšie implementovať tieto podmienky pomocou príkazu break, než sa ich snažiť vyjadriť v jedinej podmienenej slučke. Nasledujúci príklad sa pokúša nájsť prvok poľa so špecifickou hodnotou. Cyklus sa končí obvyklým spôsobom, keď sa dosiahne koniec poľa, alebo príkazom break, hneď ako sa nájde požadovaná hodnota:

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

V JavaScripte je povolené zadať názov štítka za kľúčové slovo zlom (identifikátor bez dvojbodky):

break meno_menovky;

Keď sa príkaz break použije s označením, preskočí na koniec pomenovaného príkazu alebo ukončí jeho vykonávanie. Ak neexistuje inštrukcia so špecifikovaným označením, pokus o použitie tejto formy príkazu break vygeneruje chybu syntaxe. Pomenovaný príkaz nemusí byť príkazom slučky alebo prepínača. Označený príkaz break môže „uniknúť“ z akéhokoľvek obsahujúceho príkazu. Dokonca môže byť aj priložený návod jednoduchý blok pokyny vložené do zložených zátvoriek výlučne na účely označenia.

Medzi kľúčové slovo break a názov štítka nie je možné vložiť znak nového riadku. Je to preto, že interpret JavaScript automaticky vkladá chýbajúce bodkočiarky: ak prerušíte riadok kódu medzi kľúčové slovo break a štítok, ktorý za ním nasleduje, interpret bude predpokladať, že ste mysleli jednoduchú formu tohto operátora bez štítka, a pridá bodkočiarku .

Označený príkaz break sa vyžaduje iba vtedy, keď chcete prerušiť vykonanie príkazu, ktorý nie je najbližším uzatváracím príkazom slučky alebo príkazu switch.

pokračovať vo vyhlásení

Príkaz continue je podobný príkazu break. Namiesto ukončenia cyklu však príkaz continue spustí novú iteráciu cyklu. Syntax príkazu continue je rovnako jednoduchá ako syntax príkazu break. Príkaz continue možno použiť aj s označením.

Príkaz continue, či už neoznačený alebo označený, možno použiť iba v rámci tela cyklu. Použitie kdekoľvek inde má za následok chybu syntaxe. Keď sa vykoná príkaz continue, aktuálna iterácia cyklu sa preruší a začne sa ďalšia. Pre odlišné typy cykly znamenajú rôzne veci:

    V slučke while sa znova skontroluje výraz zadaný na začiatku cyklu a ak je pravdivý, telo cyklu sa vykoná od začiatku.

    Cyklus do/while preskočí na koniec cyklu, kde sa pred opakovaním cyklu znova skontroluje podmienka.

    V slučke for sa vyhodnotí prírastkový výraz a znova sa vyhodnotí testovací výraz, aby sa určilo, či sa má vykonať ďalšia iterácia.

    V slučke for/in sa slučka začína odznova s ​​priradením zadaného názov premennejďalšia nehnuteľnosť.

Všimnite si rozdiel v správaní príkazu continue v cykloch while a for. Cyklus while sa vráti priamo do svojho stavu a pre slučku najprv vyhodnotí prírastkový výraz a potom sa vráti k podmienke. Nasledujúci príklad ukazuje použitie neoznačeného príkazu continue na ukončenie aktuálnej iterácie cyklu pre párne čísla:

var sum = 0; // Vypočítajte súčet nepárnych čísel od 0 do 10 pre (var i = 0; i

Príkaz continue, podobne ako break, možno použiť vo vnorených slučkách vo forme, ktorá obsahuje označenie, pričom v tomto prípade reštartovaný cyklus nemusí nevyhnutne obsahovať príkaz continue. Rovnako ako v prípade break nie sú povolené nové riadky medzi kľúčovým slovom continue a názvom štítka.

návratový výkaz

Volanie funkcie je výraz a ako všetky výrazy má svoju hodnotu. Príkaz return vo funkciách sa používa na určenie hodnoty vrátenej funkciou. Príkaz return možno umiestniť iba do tela funkcie. Jeho prítomnosť kdekoľvek inde je syntaktická chyba. Keď sa vykoná príkaz return, funkcia vráti hodnotu výrazu volajúcemu programu. Napríklad:

Ak funkcia nemá príkaz return, pri jej volaní tlmočník vykoná inštrukcie v tele funkcie jednu po druhej, až kým nedosiahne koniec funkcie, a potom vráti riadenie programu, ktorý ju volal. V tomto prípade sa výraz volania vráti ako nedefinovaný. Príkaz return je často posledným príkazom vo funkcii, ale je to úplne voliteľné: funkcia vráti riadenie volajúcemu programu hneď po dosiahnutí príkazu return, aj keď po ňom nasledujú ďalšie príkazy v tele funkcie.

Príkaz return možno použiť aj bez výrazu, v takom prípade jednoducho zruší funkciu a vráti volajúcemu nedefinované. Napríklad:

Funkcia myFun(arr) ( // Ak pole obsahuje záporné čísla, prerušte funkciu pre (var i = 0; i

príkaz hodiť

Výnimka je signál indikujúci výskyt nejakého druhu výnimky alebo chyby. Vyvolanie výnimky (hod) je spôsob, ako signalizovať takúto chybu alebo výnimku. Chytiť výnimku (chytiť) znamená zvládnuť, t.j. podniknúť kroky potrebné alebo vhodné na zotavenie sa z výnimky.

V JavaScripte sú výnimky vyvolané, keď sa vyskytne chyba pri spustení a keď ju program explicitne vyvolá príkazom throw. Výnimky sa zachytávajú pomocou príkazov try/catch/finally, ktoré sú popísané neskôr.

Príkaz throw má nasledujúcu syntax:

hodiť výraz;

Výsledkom výrazu môže byť hodnota akéhokoľvek typu. Príkazu throw možno odovzdať číslo predstavujúce kód chyby alebo reťazec obsahujúci text chybovej správy. Tlmočník JavaScript vyvoláva výnimky pomocou inštancie triedy chyba jednu z jeho podtried a môžete tiež použiť podobný prístup. Objekt Error má vlastnosť názov, ktorý definuje typ chyby a vlastnosť správu A obsahujúce reťazec odovzdaný funkcii konštruktora. Nasleduje príklad funkcie, ktorá pri volaní s neplatným argumentom vyvolá objekt Error:

// Faktoriálna funkcia číselnej funkcie faktoriál(číslo) ( // Ak vstupný argument nie je platná hodnota, // je vyvolaná výnimka! if (cislo 1; i *= cislo, cislo--); /* telo prázdnej slučky */ return i; ) konzola. log("5! = ", faktoriál(5)); konzola. log("-3! = ", faktoriál(-3));

Keď je vyvolaná výnimka, interpret JavaScript okamžite preruší normálne vykonávanie programu a preskočí na najbližšiu obsluhu výnimky. Obslužné programy výnimiek používajú príkaz catch konštruktu try/catch/finally, ktorý je popísaný v ďalšej časti.

Ak blok kódu, v ktorom bola vyvolaná výnimka, nemá zodpovedajúcu konštrukciu catch, interpret analyzuje nasledujúce vonkajšia jednotka programový kód a skontroluje, či je k nemu priradený obslužný program výnimky. Toto pokračuje, kým sa nenájde handler.

Ak je výnimka vyvolaná vo funkcii, ktorá neobsahuje konštrukciu try/catch/finally na jej spracovanie, potom sa výnimka rozšíri do kódu, ktorý funkciu zavolal. Týmto spôsobom sa výnimky šíria pozdĺž lexikálnej štruktúry JavaScript metódy v zásobníku hovorov. Ak sa obsluha výnimky nikdy nenájde, výnimka sa považuje za chybu a nahlási ju používateľovi.

skúsiť/chytiť/konečne postaviť

Konštrukcia try/catch/finally implementuje mechanizmus spracovania výnimiek JavaScriptu. skúste vyhlásenie v tomto konštrukte jednoducho definuje blok kódu, v ktorom sa spracúvajú výnimky. Po bloku try nasleduje vyhlásenie o úlovku s blokom príkazov, ktoré sa majú volať, ak sa kdekoľvek v bloku try vyskytne výnimka. Za príkazom catch nasleduje blok konečne A, ktorý obsahuje kód, ktorý vykonáva záverečné operácie a je zaručené, že sa spustí bez ohľadu na to, čo sa stane v bloku try.

Blok catch aj blok final sú voliteľné, ale aspoň jeden z nich musí byť prítomný po bloku try. skúšaj, chytaj a nakoniec bloky začínajú a končia kučeravé zátvorky. Toto je povinná časť syntaxe a nemožno ju vynechať, aj keď je medzi nimi iba jeden príkaz.

Nasledujúci úryvok ilustruje syntax a účel konštrukcie try/catch/finally:

Skúste ( // Za normálnych okolností tento kód pobeží hladko od začiatku do konca. // V určitom okamihu však môže vyvolať výnimku, // buď priamo príkazom throw, alebo nepriamo, // volaním metódy, ktorá vyvolá výnimka. ) catch (ex) ( // Príkazy v tomto bloku sa vykonajú vtedy a len vtedy, ak sa v bloku try // vyskytne výnimka. Tieto príkazy môžu používať lokálnu premennú ex, ktorá // odkazuje na objekt Error alebo na iný hodnota zadaná v príkaze throw. // Tento blok môže buď spracovať výnimku nejakým spôsobom, alebo // ju ignorovať a urobiť niečo iné, alebo // vrátiť výnimku príkazom throw. ) nakoniec ( // Tento blok obsahuje príkazy ktoré sa vykonajú vždy, bez ohľadu na to, či , // čo sa stalo v bloku try Vykonajú sa, ak sa blok try skončil: // 1) ako zvyčajne, dosiahnutím konca bloku // 2) kvôli prerušeniu, pokračovaniu alebo návratu príkazy // 3) s výnimkou spracovanou v bloku catch vyššie // ​​4) s nezachytenou výnimkou, ktorá sa naďalej // šíri na vyššie úrovne)

Všimnite si, že za kľúčovým slovom catch nasleduje identifikátor v zátvorkách. Tento identifikátor je podobný parametru funkcie. Keď sa zachytí výnimka, tento parameter sa nastaví na výnimku (napríklad objekt Error). Na rozdiel od normálnej premennej, identifikátor spojený s príkazom catch existuje iba v tele bloku catch.

Nasleduje realistickejší príklad konštrukcie pokus/úlovok. Volá metódu factorial() definovanú v predchádzajúcom príklade a promptné metódy() a alert() JavaScript na strane klienta na usporiadanie vstupu a výstupu:

Skúste ( // Požiadajte používateľa o číslo var n = Number(prompt("Zadajte kladné číslo", "")); // Vypočítajte faktoriál čísla za predpokladu, že // je vstup platný var f = faktoriál( n); // Vytlačiť upozornenie na výsledok (n + "! = " + f); ) catch (ex) ( // Ak sú údaje nesprávne, kontrola sa prenesie sem alert(ex); // Upozorniť používateľa na chyba)

Ak používateľ zadá záporné číslo, zobrazí sa varovné hlásenie:

Toto je príklad konštrukcie try/catch bez príkazu final. Aj keď sa nakoniec nepoužíva tak často ako catch, niekedy je to užitočné. Spustenie bloku konečne je zaručené, ak sa vykonala aspoň nejaká časť bloku try, bez ohľadu na to, ako skončil kód v bloku try. Táto funkcia sa zvyčajne používa na vykonávanie záverečných operácií po vykonaní kódu v pokračovaní pokusu.

V normálnej situácii sa kontrola dostane na koniec bloku try a potom preskočí na blok final, ktorý vykoná potrebné záverečné operácie. Ak ovládací prvok opustí blok try v dôsledku príkazu return, continue alebo break, vykoná sa posledný blok predtým, ako sa riadenie prenesie inam.

Ak sa v bloku try vyskytne výnimka a existuje vhodný blok catch na jej spracovanie, riadenie sa najskôr prenesie do bloku catch a potom do bloku nakoniec. Ak neexistuje žiadny blok lokálneho zachytenia, potom kontrola najprv prejde do bloku konečnej a potom preskočí na najbližší vonkajší blok, ktorý dokáže spracovať výnimku.

Ak samotný blok konečne prenesie riadenie pomocou príkazu return, continue, break alebo throw alebo volaním metódy, ktorá vyvolá výnimku, čakajúci príkaz na prenos sa zruší a vykoná sa nový. Ak napríklad blok konečne vyvolá výnimku, táto výnimka nahradí akúkoľvek predtým vyvolanú výnimku.

Operátor vrátiť ukončí aktuálnu funkciu a vráti jej hodnotu.

Zdrojový kód tohto interaktívneho príkladu je uložený v úložisku GitHub. Ak sa chcete zúčastniť projektu interaktívne príklady prosím klonujte https://github.com/mdn/interactive-examples

Syntax

návrat [[výraz]]; výraz Výraz, ktorého hodnota bude vrátená. Ak nie je zadaný, vráti sa namiesto neho undefined.

Popis

Keď sa vo funkcii zavolá príkaz return, jeho vykonávanie sa zastaví. Zadaná hodnota sa vráti na miesto, kde bola funkcia volaná. Napríklad nasledujúca funkcia vráti druhú druhú hodnotu svojho argumentu x (kde x je číslo):

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

Ak nie je zadaná žiadna návratová hodnota, namiesto toho sa vráti hodnota undefined.

Nasledujúce výrazy vždy ukončia vykonávanie funkcie:

návrat; vrátiť true; vrátiť nepravdu; návrat x; návrat x + y / 3;

Automatické bodkočiarky

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

technické údaje

Špecifikácia Postavenie Komentujte
ECMAScript 1. vydanie (ECMA-262) Štandardné pôvodná definícia
ECMAScript 5.1 (ECMA-262)
Štandardné
ECMAScript 2015 (6. vydanie, ECMA-262)
Definícia "výpisu o vrátení" v tejto špecifikácii.
Štandardné
Najnovší koncept ECMAScript (ECMA-262)
Definícia "výpisu o vrátení" v tejto špecifikácii.
Návrh

Kompatibilita prehliadača

Tabuľka kompatibility na tejto stránke je vygenerovaná zo štruktúrovaných údajov. Ak by ste chceli prispieť k údajom, pozrite si ich z úložiska https://github.com/mdn/browser-compat-data a pošlite nám žiadosť o vykonanie zmien.

Aktualizujte údaje o kompatibilite na GitHub

PočítačeMobilnéserver
ChromehranaFirefoxinternet ExplorerOperasafariandroid webviewChrome pre AndroidFirefox pre AndroidOpera pre AndroidSafari na iOSInternet SamsungNode.js
vrátiťChrome Plná podpora 1 hrana Plná podpora 12 Firefox Plná podpora 1 IE Plná podpora 3 Opera Plná podporaÁnosafari Plná podporaÁnowebview android Plná podpora 1 Chrome pre Android Plná podpora 18 Firefox Android Plná podpora 4 OperaAndroid Plná podporaÁnoSafari iOS Plná podporaÁnoSamsung Internet Android Plná podpora 1.0 nodejs Plná podporaÁno