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

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, počítání odmocnin atd.).

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

Deklarace funkce

1. Syntaxe:

//Deklarace funkce functionFunctionname(ln1, ln2)( Kód funkce) //Volání funkceFunctionname(ln1,lr2);

2. Syntaxe:

//Deklarace funkce var function name=function(ln1, ln2)(Kód funkce) //Volání funkce name function(ln1,lr2);

functionname 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 číslicemi.

ln1 a ln2 jsou proměnné nebo hodnoty, které lze předat funkci. Každé funkci lze předat neomezený počet proměnných.

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

Upozorňujeme, že názvy funkcí v JavaScriptu rozlišují velká a malá písmena.

Příklad Funkce JavaScriptu

Funkce messageWrite() v příkladu níže bude provedena pouze po kliknutí na tlačítko.

Všimněte si, že tento příklad používá událost onclick. Události JavaScriptu budou podrobně popsány později v tomto tutoriálu.

// Funkce zapíše text do funkce stránky messageWrite() ( document.write("Tento text byl na stránku zapsán pomocí JavaScriptu!"); )

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

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

Upozornění: veškeré 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í.

/* Definujme funkci, která přidá 10 k předané proměnné a zobrazí výsledek na stránce */ 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+"
"); // Volání funkce předáním proměnné a 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

Pomocí příkazu return můžete vrátit hodnoty z funkcí.

//Funkce sum vrací součet proměnných, které jí byly předány function sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + suma(10,4) + "
");

Rychlý pohled

Vestavěné funkce

Kromě uživatelsky definovaných funkcí má JavaScript také vestavěné funkce.

Například vestavěná funkce isFinite 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é

Proměnné vytvořené uvnitř funkcí se nazývají 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 dokončení provádění 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.

Proměnné, které jsou vytvořeny mimo funkční kód, se nazývají globální proměnné; k takovým 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 až po zavření stránky.

//Deklarování globálních proměnných var1 a var2 var var1="var1 existuje"; var var2; function func1() ( //Přiřaďte var2 hodnotu uvnitř funkce func1 var var2="var2 existuje"; ) //Z jiné funkce vypíše obsah proměnné var1 a var2 do funkce stránky func2() ( //Output obsah proměnné var1 document.write( var1 + "
"); //Vypíše obsah proměnné var2 document.write(var2); )

Rychlý pohled

Všimněte si, že při tisku na obrazovku bude mít var2 prázdnou hodnotu, protože funkce func1 funguje na místní "verzi" var2.

Použití anonymních funkcí

Funkce, které při deklaraci neobsahují název, se nazývají anonymní.

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

Funkce arrMap(arr,func)( var res=new Array; for (var i=0;i 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 mu jakékoli. Neočekávám, že okamžitě pochopíte, jak program funguje. Ale pojďme pochopit toto skvělé cvičení v rekurzivním myšlení.

Vnitřní funkce find provádí rekurzi. Vyžaduje dva argumenty – aktuální číslo a řetězec, který obsahuje záznam, jak jsme k tomuto číslu dospěli. A vrací buď řetězec ukazující naši sekvenci kroků, nebo null.

K tomu funkce provede jednu ze tří akcí. Pokud se dané číslo rovná cíli, pak aktuální příběh je právě způsob, jak toho dosáhnout, takže se vrací. Pokud je dané číslo větší než cíl, nemá smysl dále násobit a sčítat, protože se bude jen zvyšovat. A pokud jsme ještě nedosáhli cíle, funkce zkouší obě možné cesty počínaje daným číslem. Přivolá se dvakrát, jednou pro každou metodu. Pokud první volání nevrátí hodnotu null, je vráceno. V jiném případě se vrátí druhý.

Abychom lépe pochopili, jak funkce dosahuje požadovaného účinku, podívejme se na volání, která provádí, abychom našli ř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í na (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á vytvářejí číslo menší nebo rovné požadovanému číslu. Nenajde a vrátí hodnotu null. Potom operátor || a přejde k volání funkce, která zkoumá volbu (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 || po cestě míjí tuto čáru výše, což má za následek návrat řešení.

Rostoucí funkce Existují dvě více nebo méně přirozenou cestou zadávání funkcí do programu.

První je, že podobný kód napíšete několikrá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, dáme jí dobré jméno a vložíme ji 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ředtím, než byla 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 je třeba přidat nuly, aby každé obsadilo právě tři pozice.

007 Krávy 011 Kuřata

Je zřejmé, že potřebujeme funkci se dvěma argumenty. Začněme kódovat.
// tisk funkce FarmInventory 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 zatímco smyčky přidávejte k číslům úvodní nuly, dokud nezískáte tříznakový řetězec.

Připraveno! Ale právě když jsme se chystali 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 zobrazení počtu prasat do program?

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:

// výstup WITH funkce přidávání nul A štítků 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, přidávání nul a štítek – do jedné funkce. Namísto vkládání celého opakujícího se fragmentu do funkce zdůrazněme jeden koncept:

// přidání funkce nula 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 a jasný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 univerzální by měly být funkce? Můžeme napsat buď jednoduchou funkci, která doplní číslo nulami až na tři pozice, nebo sofistikovanou funkci obecný účel pro formátování čísel, podporu zlomků, záporných čísel, zarovnání teček, vyplnění různými znaky atd.

Dobrým pravidlem je přidávat pouze funkce, o kterých víte, že budou užitečné. Někdy je lákavé vytvořit univerzální rámce pro každou malou potřebu. Odolejte mu. Práci nikdy nedokončíte, jen skončíte u psaní hromady kódů, 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, se nazývá, protože má vedlejší účinek: vytiskne řetězec. Druhý, zeroPad, kvůli návratové hodnotě. A není náhoda, že druhá funkce se hodí častěji než ta první. Funkce, které vracejí hodnoty, se dají snáze kombinovat než funkce, které mají vedlejší účinky.

Č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é by mohly být náhodně změnili 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é. Snadno se s ní pracuje. 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 daném kontextu, bude fungovat v jakémkoli kontextu. Méně čisté funkce mohou vracet různé výsledky v závislosti na mnoha faktorech a mít vedlejší účinky, které se obtížně testují a zohledňují.

Neměli byste se však stydět napsat funkce, které nejsou zcela čisté, nebo začít s posvátným kódovým čištěním takových funkcí. Vedlejší účinky jsou často prospěšné. Neexistuje způsob, jak napsat čistou verzi funkce console.log a tato funkce je docela užitečná. Některé operace lze snadněji vyjádřit pomocí vedlejších účinků.

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

Klíčem k pochopení funkcí je místní rozsah. Parametry a proměnné deklarované uvnitř funkce jsou pro ni lokální, jsou znovu vytvořeny při každém jejím volání a nejsou zvenčí viditelné. 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 smysluplné části, stejně jako kapitoly a části knihy pomáhají organizovat běžný text.

CvičeníMinimum V předchozí kapitole jsme zmínili funkci Math.min, která vrací nejmenší ze svých argumentů. Nyní si takovou funkci můžeme napsat sami. Napsat funkce 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 % (modulo) lze použít k určení, zda je číslo (%2) sudé. Zde je další způsob, jak to definovat:

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

Napište rekurzivní funkci isDokonce podle těchto pravidel. Musí přijmout číslo a vrátit booleovskou hodnotu.

Otestujte to na 50 a 75. Zkuste to dát -1. Proč se chová tímto způsobem? Je možné to nějak opravit?

Otestujte to na 50 a 75. Podívejte se, jak se chová na -1. Proč? Napadá vás způsob, jak to opravit?

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

Počítání fazolí.

Číslo znaku N řetězce lze získat přidáním .charAt(N) („řetězec“.charAt(5)) k němu – podobným způsobem jako při získávání délky řetězce pomocí .length. Vrácenou hodnotou bude řetězec skládající se z jednoho znaku (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“ obsažených v řetězci.

Poté napište funkci nazvanou countChar, která funguje něco jako countBs, ale vezme si 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řepracujte funkci countBs.