Pět způsobů volání funkce. Funkční programování

Funkce

Funkce je blok kódu JavaScript, který je definován jednou a lze jej spustit nebo zavolat vícekrát. Možná jste již obeznámeni s konceptem funkce pod jiným názvem, jako je například podprogram nebo procedura. Funkce mohou mít parametry: Definice funkce může obsahovat seznam identifikátorů, které se nazývají parametry a fungují jako lokální proměnné v těle funkce.

Když jsou funkce volány, mohou jim být předány hodnoty nebo argumenty odpovídající jejich parametrům. Funkce často používají své argumenty k výpočtu návratové hodnoty, což je hodnota výrazu volání funkce. Kromě argumentů je při volání jakékoli funkce předána ještě jedna hodnota, která definuje kontext volání – hodnota v klíčovém slově this.

Funkce v JavaScriptu jsou objekty a lze je používat různými způsoby. Funkce mohou být například přiřazeny proměnným a předány jiným funkcím. Protože funkce jsou objekty, můžete jejich vlastnostem přiřadit hodnoty a dokonce volat jejich metody.

JavaScript umožňuje vnoření definic funkcí do jiných funkcí a takové funkce budou mít přístup ke všem proměnným přítomným v rozsahu definice.

Definování funkcí

Definice funkce začíná klíčovým slovem function, za kterým následují následující komponenty:

Identifikátor, který určuje název funkce

Název je povinnou součástí příkazu deklarace funkce: bude použit k vytvoření nové proměnné, ke které bude přiřazen nový funkční objekt. Ve výrazech definice funkce může název chybět: pokud je přítomen, bude název odkazovat na objekt funkce pouze v těle samotné funkce.

Dvojice závorek kolem seznamu nula nebo více identifikátorů oddělených čárkami

Tyto identifikátory budou definovat názvy parametrů funkce a lze je použít jako lokální proměnné v těle funkce.

Dvojice složených závorek s žádnými nebo více pokyny pro JavaScript uvnitř

Tyto instrukce tvoří tělo funkce: provádějí se pokaždé, když je funkce volána.

Následující příklad ukazuje několik definic funkcí ve formě příkazů a výrazů. Všimněte si, že definice funkcí jako výrazy jsou užitečné pouze v případě, že jsou součástí větších výrazů, jako je přiřazení nebo volání funkce, které něco dělají s nově deklarovanou funkcí:

// Vypíše názvy a hodnoty všech vlastností objektu obj funkce printprops(obj) ( for(var p v obj) console.log(p + ": " + obj[p] + "\n"); ) // Vypočítá vzdálenost mezi body (x1,y1) a (x2,y2) funkce distance(x1, y1, x2, y2) ( var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx *dx + dy*dy ) // Rekurzivní funkce (volá sama sebe), která vypočítá faktoriál faktorial(x) ( if (x)

Všimněte si, že ve výrazech definice funkce nemusí být název funkce přítomen. Příkaz deklarace funkce ve skutečnosti deklaruje proměnnou a přiřadí jí funkční objekt.

Na druhé straně výraz definice funkce nedeklaruje proměnnou. V definičních výrazech je však možné zadat název funkce, jako ve výše uvedené faktoriálové funkci, což může být vyžadováno v těle funkce, aby se sama zavolala. Pokud výraz definice funkce obsahuje název, bude tento název odkazovat na funkční objekt v rozsahu dané funkce. Ve skutečnosti se název funkce stává lokální proměnnou, která je přístupná pouze v těle funkce. Ve většině případů nemusí být název funkce uveden v definičních výrazech, takže definice jsou kompaktnější.

Všimněte si, že většina (ale ne všechny) funkcí v příkladu obsahuje příkaz return. Příkaz return ukončí funkci a vrátí hodnotu jejího výrazu (pokud je zadán) volajícímu programu. Pokud v příkazu return není žádný výraz, vrátí nedefinovaný. Pokud ve funkci není žádný příkaz return, interpret jednoduše provede všechny příkazy v těle funkce a vrátí volajícímu programu nedefinovaný.

Většina funkcí v příkladu se vyhodnotí na nějakou hodnotu a pomocí příkazu return vrátí tuto hodnotu volajícímu programu. Funkce printprops() je v tomto smyslu mírně odlišná: jejím úkolem je tisknout názvy vlastností objektu. Nemusí vracet žádnou hodnotu, takže ve funkci není žádný příkaz return. Funkce printprops() vždy vrátí hodnotu nedefinovaná. (Funkce, které nemají návratovou hodnotu, se někdy nazývají procedury.)

Volání funkcí

Programový kód, který tvoří tělo funkce, se nespustí v okamžiku, kdy je funkce definována, ale v okamžiku, kdy je volána. Volání funkcí se provádí pomocí výrazu volání. Volací výraz se skládá z výrazu volání funkce, který vrací objekt funkce následovaný závorkami se seznamem nulových nebo více argumentů oddělených čárkami uvnitř.

Pokud je výraz volání funkce výraz volání vlastnosti – pokud je funkce vlastností objektu nebo prvku pole (tj. metoda) – pak výraz volání je výraz volání metody. Následující úryvek ukazuje několik příkladů běžných výrazů volání funkcí:

Printprops((x:4, věk: 24)); var d = vzdálenost(1,1,5,6); var f = faktoriál(5) / faktoriál(12); f = čtverec(5);

Při volání funkce se vyhodnotí všechny výrazy argumentů (uvedené v závorkách) a výsledné hodnoty se použijí jako argumenty funkce. Tyto hodnoty jsou přiřazeny parametrům, jejichž názvy jsou uvedeny v definici funkce. V těle funkce vrátí výrazy volání parametrů hodnoty odpovídajících argumentů.

Když je volána normální funkce, návratová hodnota funkce se stane hodnotou volajícího výrazu. Pokud se funkce vrátí poté, co interpret dosáhl svého konce, vrátí se undefined. Pokud se funkce vrátí jako výsledek příkazu return, je vrácena hodnota výrazu následujícího po příkazu return nebo nedefinovaná, pokud příkaz return neobsahuje žádný výraz.

Metoda není nic jiného než funkce, která je uložena jako vlastnost objektu. Pokud máte funkci func a objekt obj, můžete definovat metodu na obj s názvem metoda, jak je uvedeno níže:

// Definice jednoduchého objektu a funkce var obj = (); function func(a, b) ( return a+b;) // Přidání metody do objektu obj obj.method = func; // Nyní můžete tuto metodu zavolat var result = obj.method(4, 5);

Nejčastěji se při volání metod používá forma přístupu k vlastnosti pomocí operátoru tečka, ale lze použít i formu přístupu k vlastnosti pomocí hranatých závorek. Například oba následující výrazy jsou výrazy volání metody:

Vysledek = obj.method(4, 5); vysledek = obj["metoda"](4, 5);

Argumenty a návratová hodnota volání metody jsou zpracovány přesně stejným způsobem jako normální volání funkce. Volání metody má však jeden důležitý rozdíl: kontext volání. Výraz pro přístup k vlastnosti se skládá ze dvou částí: objektu (v tomto případě obj) a názvu vlastnosti (metody). V takových výrazech volání metody se obj stává volajícím kontextem a tělo funkce je schopno odkazovat na tento objekt pomocí klíčového slova this. Například:

Var obj = ( x: 0, y: 0, // Přidat metodu: funkce(a, b) ( this.x = a; this.y = b; ), // Další součet metody: funkce() ( vrátit toto .x + this.y )); // Volání metod obj.add(15, 4); console.log(obj.sum()); // 19

Metody a klíčové slovo this jsou stěžejní pro paradigma objektově orientovaného programování. Jakákoli funkce použitá jako metoda ve skutečnosti přijímá implicitní argument - objekt, na kterém byla volána. Metody obvykle provádějí nějakou operaci s objektem a syntaxe volání metody jasně odráží skutečnost, že funkce pracuje s objektem.

Poznámka: toto je klíčové slovo, nikoli název proměnné nebo vlastnosti. Syntaxe JavaScriptu neumožňuje elementu this přiřadit hodnotu.

Funkční argumenty a parametry

V JavaScriptu definice funkcí neurčují typy parametrů a volání funkcí neprovádějí žádnou kontrolu typu předávaných hodnot argumentů. JavaScript ve skutečnosti ani nekontroluje počet argumentů při volání funkcí. Níže uvedené pododdíly popisují, co se stane, pokud je počet argumentů ve volání funkce menší nebo větší než počet deklarovaných parametrů. Ukazují také, jak můžete explicitně zkontrolovat typy argumentů funkce, pokud potřebujete zajistit, aby funkce nebyla volána s neplatnými argumenty.

Nepovinné argumenty

Když je počet argumentů ve volání funkce menší než počet deklarovaných parametrů, jsou chybějící argumenty nastaveny na nedefinováno. Často je vhodné psát funkce tak, že některé argumenty jsou nepovinné a lze je při volání funkce vynechat. V tomto případě je žádoucí poskytnout možnost přiřadit přiměřeně rozumné výchozí hodnoty parametrům, které mohou být vynechány. Například:

// Přidejte vyčíslitelná jména // vlastností objektu obj do pole arr a vraťte jej. Pokud argument // arr nebyl předán, vytvořte a vraťte novou funkci pole getPropertyNames(obj, /* volitelné */ arr) ( if (arr === nedefinováno) arr = ; // Pokud pole není definováno, vytvořte a new for( vlastnost var v obj) arr.push(property return arr // Tuto funkci lze volat s 1 nebo 2 argumenty: var a = getPropertyNames((x:1, y:1)); // Získání vlastností objektu v novém poli getPropertyNames((z:5),a); // přidá vlastnosti nového objektu do tohoto pole console.log(a); // ["x", "y", "z"]

Všimněte si, že při deklaraci funkcí musí volitelné argumenty doplnit seznam argumentů, aby byly vynechány. Programátor, který bude psát volání vaší funkce, nebude moci předat druhý argument a zároveň vynechat první: bude nucen explicitně předat hodnotu nedefinovanou v prvním argumentu. Všimněte si také komentáře /* optional */ v definici funkce, který zdůrazňuje skutečnost, že parametr je volitelný.

Seznamy argumentů s proměnnou délkou

Pokud počet argumentů ve volání funkce překročí počet názvů parametrů, funkce nebude moci přímo přistupovat k nepojmenovaným hodnotám. Řešení tohoto problému poskytuje objekt Arguments. V těle funkce odkazuje identifikátor argumentů na objekt Arguments přítomný ve volání. Objekt Arguments je objekt podobný poli, který umožňuje, aby hodnoty předané funkci byly načteny podle jejich čísel, nikoli podle jejich jmen.

Předpokládejme, že byla definována funkce func, která vyžaduje jeden argument x. Pokud tuto funkci zavoláte se dvěma argumenty, první bude dostupný uvnitř funkce pod názvem parametru x nebo jako argumenty. Druhý argument bude dostupný pouze jako argumenty. Navíc, stejně jako skutečná pole, mají argumenty vlastnost length, která určuje počet prvků, které obsahuje. To znamená, že v těle funkce zvané func se dvěma argumenty má arguments.length hodnotu 2.

Objekt Arguments lze použít pro různé účely. Následující příklad ukazuje, jak jej použít ke kontrole, zda byla funkce volána se správným počtem argumentů, což JavaScript za vás neudělá:

Funkce func(x, y, z) ( // Nejprve zkontroluje, zda je předán správný počet argumentů if (arguments.length != 3) ( vyvolá novou chybu Error("Func volána s argumenty " + arguments.length + " a požadované 3."); ) // A nyní samotný kód funkce... )

Všimněte si, že často není nutné kontrolovat počet argumentů, jako v tomto příkladu. Výchozí chování interpretu JavaScriptu je ve většině případů v pořádku: chybějící argumenty jsou nahrazeny hodnotou undefined a další argumenty jsou jednoduše ignorovány.

Objekt Arguments ilustruje důležitou vlastnost funkcí JavaScriptu: mohou být zapsány tak, aby přebíraly libovolný počet argumentů. Následující funkce přebírá libovolný počet argumentů a vrací hodnotu největšího z nich (vestavěná funkce Math.max() se chová podobně):

Funkce maxNumber() ( var m = Číslo.NEGATIVE_INFINITY; // Procházet všechny argumenty, najít a // uložit největší z nich pro (var i = 0; i m) m = argumenty[i]; // Vrácení největší hodnoty m ; ) var největší = maxNumber(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // 10 000

Funkce, jako je tato, které mohou mít libovolný počet argumentů, se nazývají variadické funkce, funkce proměnné arity nebo funkce varargs. Tento termín vznikl s příchodem programovacího jazyka C.

Všimněte si, že nesmí být povoleno volání variadic funkcí s prázdným seznamem argumentů. Je naprosto smysluplné použít objekt arguments při psaní funkce, která očekává pevný počet požadovaných pojmenovaných argumentů, za nimiž následuje libovolný počet nepovinných nepojmenovaných argumentů.

Nezapomeňte, že argumenty ve skutečnosti nejsou pole – je to objekt Argumenty. Každý objekt Arguments má očíslované prvky pole a vlastnost length, ale technicky se nejedná o pole. Je lepší si to představit jako objekt, který má nějaké očíslované vlastnosti.

Kromě prvků pole definuje objekt Arguments vlastnosti volaného a volajícího. Pokus o změnu hodnot těchto vlastností v přísném režimu ECMAScript 5 zaručeně vyvolá výjimku TypeError. V laxním režimu však standard ECMAScript uvádí, že vlastnost volaného odkazuje na aktuálně prováděnou funkci. Vlastnost caller není standardní, ale je přítomna v mnoha implementacích a odkazuje na funkci, která volala aktuální.

Vlastnost caller může být použita pro přístup k zásobníku volání a vlastnost callee je zvláště užitečná pro rekurzivní volání nepojmenovaných funkcí:

Proměnný faktoriál = funkce (x) ( if (x

Vlastnosti a metody funkce

Viděli jsme, že funkce mohou být použity jako hodnoty v programech JavaScript. Operátor typeof vrací pro funkce řetězec "funkce", ale funkce jsou ve skutečnosti speciálním druhem objektů v JavaScriptu. A protože funkce jsou objekty, mají vlastnosti a metody jako jakékoli jiné objekty. Existuje dokonce konstruktor Function(), který vytváří nové funkční objekty. Následující podkapitoly popisují vlastnosti a metody funkcí.

vlastnost délky

Vlastnost arguments.length v těle funkce určuje počet argumentů předávaných funkci. Vlastní délka funkce má však jiný význam. Tato vlastnost pouze pro čtení vrací počet argumentů, které funkce očekává, že obdrží – počet deklarovaných parametrů.

Následující úryvek definuje funkci nazvanou check(), která přijímá pole argumentů z jiné funkce. Porovná vlastnost arguments.length (počet skutečně předaných argumentů) s vlastností arguments.callee.length (počet očekávaných argumentů), aby určil, zda bylo funkci předáno tolik argumentů, kolik očekává. Pokud se hodnoty neshodují, je vyvolána výjimka. Po funkci check() následuje testovací funkce func(), která ukazuje, jak používat funkci check():

// Tato funkce používá arguments.callee, takže // nebude fungovat v přísném režimu funkce check(args) ( var Actual = args.length; // Skutečný počet argumentů var expect = args.callee.length; // Očekávané počet argumentů if (skutečné !== očekávané) // Pokud se neshodují, je vyvolána výjimka throw new Error("expected: " + očekávané + "; přijato " + skutečné ) funkce func(x, y, z) ( // Kontrola počtu očekávaných a skutečně prodaných argumentů check(arguments // Nyní proveďte zbytek funkce return x + y + z);

vlastnost prototypu

Každá funkce má vlastnost prototypu, která odkazuje na objekt známý jako objekt prototypu. Každá funkce má svůj vlastní prototypový objekt. Když je funkce použita jako konstruktor, nově vytvořený objekt zdědí vlastnosti tohoto prototypového objektu.

Prototypy a vlastnosti prototypu byly probrány v předchozím článku.

metody call() a apply().

Metody call() a apply() umožňují volat funkci nepřímo, jako by to byla metoda na nějakém jiném objektu. První argument pro metody call() a apply() je objekt, na kterém je funkce volána; tento argument určuje kontext volání a stává se hodnotou klíčového slova this v těle funkce. Chcete-li volat funkci func() (bez argumentů) jako metodu obj, můžete použít kteroukoli z metod call() nebo apply():

Func.call(obj); func.apply(obj);

Oba způsoby jeho volání jsou ekvivalentní následujícímu fragmentu (za předpokladu, že obj nemá vlastnost s názvem m):

Obj.m = func; // Dočasně udělá z func metodu obj obj.m(); // Zavolejte to bez argumentů. deleteobj.m; // Odstraňte dočasnou metodu.

V přísném režimu ECMAScript 5 se první argument metod call() a apply() stává hodnotou této, i když je to jednoduchá hodnota, null nebo nedefinovaná. V ECMAScript 3 a v laxním režimu jsou hodnoty null a undefined nahrazeny globálním objektem a jednoduchá hodnota je nahrazena odpovídajícím obalem.

Všechny ostatní argumenty metody call() následující po prvním argumentu určujícím kontext volání jsou předány volané funkci. Metoda apply() se chová jako metoda call() kromě toho, že argumenty funkce jsou předány jako pole. Pokud je funkce schopna zpracovat libovolný počet argumentů, lze k volání takové funkce použít metodu apply() v kontextu pole libovolné délky.

Následující příklad ukazuje praktické použití metody call():

// Níže jsou uvedeny dvě funkce, které zobrazují vlastnosti a // hodnoty vlastností libovolného objektu. Metoda // displeje jsou předány jako argument funkce func print1(func, obj) ( for (n v obj) func(n +": " + obj[n]); ) funkce print2(func, objDevice, obj) ( for ( n v obj) func.call(objDevice, n +": " + obj[n] ) var obj = (x:5, y:10); print2(dokument.zapis, dokument, obj); // Funguje správně print2(console.log, console, obj); tisk1(dokument.zápis, obj); // Dojde k výjimce neplatného vyvolání, protože print1(console.log, obj); // není možné volat tyto metody bez kontextového objektu

metoda bind().

Metoda bind() se poprvé objevila v ECMAScriptu 5, ale lze ji snadno napodobit v ECMAScriptu 3. Jak její název napovídá, hlavním účelem metody bind() je svázat funkci s objektem. Pokud zavoláte metodu bind() funkce func a předáte jí objekt obj, vrátí novou funkci. Volání nové funkce (jako běžné funkce) zavolá původní funkci func jako metodu na obj. Všechny argumenty předané nové funkci budou předány původní funkci. Například:

// Funkce, kterou chcete svázat funkci func(y) ( return this.x + y; ) var obj = (x:1); // Objekt pro vazbu na var g = func.bind(obj); // Volání g(x) zavolá obj.func(x)

Tento typ vazby lze snadno implementovat v ECMAScript 3, jak je znázorněno níže:

// Vrátí funkci, která volá funkci func jako metodu objektu obj // a předá jí všechny své argumenty function bind(func, obj) ( if (func.bind) return func.bind(obj); // Use bind method if dostupné else return function() ( // Jinak svázat, jak je ukázáno níže return func.apply(obj, arguments); )

Metoda bind() v ECMAScript 5 dělá více než jen váže funkci k objektu. Provádí také částečné přetypování: kromě hodnoty this budou svázány všechny argumenty předané metodě bind() po jejím prvním argumentu. Částečná aplikace je běžná technika ve funkcionálním programování a někdy se jí říká kari.

  • Překlad

Často se setkávám s kódem JavaScriptu, kde jsou chyby způsobeny nepochopením toho, jak funkce v JavaScriptu fungují (mimochodem, velkou část tohoto kódu jsem napsal já). JavaScript je multiparadigmatický jazyk a má funkční programovací mechanismy. Je čas prozkoumat tyto možnosti. V tomto článku vám řeknu pět způsobů, jak volat funkce v JavaScriptu.

V raných fázích učení JavaScriptu si začátečníci obvykle myslí, že funkce v něm fungují v podstatě stejným způsobem jako například v C#. Mechanismy pro volání funkcí v JavaScriptu mají ale řadu důležitých rozdílů a jejich neznalost může mít za následek chyby, které nebude snadné najít.

Pojďme napsat jednoduchou funkci, která vrátí pole tří prvků – aktuální hodnotu this a dva argumenty předané funkci.
function makeArray(arg1, arg2)( return [ this, arg1, arg2 ]; )

Nejběžnější způsob: globální volání Začátečníci často deklarují funkce, jak je uvedeno v příkladu výše. Volání této funkce je snadné:
makeArray("jeden", "dva"); // => [ okno, "jeden", "dva" ]
Počkejte. Odkud pochází objekt okna? Proč se to rovná oknu?

V JavaScriptu, bez ohledu na to, zda je skript spuštěn v prohlížeči nebo v jiném prostředí, je vždy definován globální objekt. Jakýkoli kód v našem skriptu, který není „vázán“ na nic (tj. mimo deklaraci objektu), je ve skutečnosti v kontextu globálního objektu. V našem případě není makeArray pouze funkcí, která „chodí“ sama o sobě. MakeArray je ve skutečnosti metoda okna globálního objektu (v případě spuštění kódu v prohlížeči). Je snadné dokázat:
alert(typeof window.methodThatNeexistuje); // => undefined alert(typeof window.makeArray); // => funkce
To znamená volání makeArray("jeden", "dva"); je ekvivalentní volání window.makeArray("jeden", "dva"); .

Je mi smutno, že je to nejběžnější způsob volání funkcí, protože to znamená přítomnost globální funkce. A všichni víme, že globální funkce a proměnné nejsou nejlepší formou v programování. To platí zejména pro JavaScript. Vyhněte se globálním definicím a nebudete litovat.

Pravidlo č. 1 volání funkce: Pokud je funkce volána přímo, bez určení objektu (například myFunction()), bude hodnota tohoto globálního objektu (okno, pokud je kód spuštěn v prohlížeči).

Volání metody Vytvořme jednoduchý objekt a udělejme z makeArray jeho metodu. Pojďme deklarovat objekt pomocí doslovného zápisu a pak zavolejte naši metodu:
// vytvoření objektu var arrayMaker = ( someProperty: "nějaká hodnota", make: makeArray ); // volání metody make() arrayMaker.make("jeden", "dva"); // => [ arrayMaker, "jeden", "dva" ] // alternativní syntaxe, použijte hranaté závorky arrayMaker["make"]("jeden", "dva"); // => [ arrayMaker, "jeden", "dva" ]
Vidíte ten rozdíl? Hodnota toho je v tomto případě samotný objekt. Proč ne window , jako v předchozím případě, protože deklarace funkce se nezměnila? Tajemství je v tom, jak jsou funkce předávány v JavaScriptu. Funkce je standardní typ JavaScriptu, který je ve skutečnosti objektem, a jako každý jiný objekt lze funkce předávat a kopírovat. V tomto případě jsme v podstatě zkopírovali celou funkci, včetně seznamu argumentů a těla, a přiřadili výsledný objekt vlastnosti make objektu arrayMaker. To je ekvivalentní tomuto prohlášení:
var arrayMaker = ( someProperty: "Nějaká hodnota"; make: function (arg1, arg2) ( return [ this, arg1, arg2]; ) );
Pravidlo #2 volání funkce: Ve funkci volané pomocí syntaxe volání metody, jako je obj.myFunction() nebo obj["myFunction"]() , bude mít hodnotu obj .

Nepochopení tohoto obecně jednoduchého principu často vede k chybám při zpracování událostí:
function buttonClicked())( var text = (toto === okno) ? "okno" : this.id; alert(text); ) var button1 = document.getElementById("btn1"); var button2 = document.getElementById("btn2"); button1.onclick = buttonClicked; button2.onclick = function())( buttonClicked(); );
Po kliknutí na první tlačítko se zobrazí zpráva "btn1" protože v tomto případě voláme funkci jako metodu a ta uvnitř funkce získá hodnotu objektu, ke kterému tato metoda patří. Kliknutím na druhé tlačítko se zobrazí "okno" protože v tomto případě voláme buttonClicked přímo (tj. ne jako obj.buttonClicked()). Totéž se stane, když tagu elementu přiřadíme handler události, jako v případě třetího tlačítka. Kliknutím na třetí tlačítko se zobrazí stejná zpráva jako na druhé.

Při používání knihoven jako jQuery na to nemusíte myslet. jQuery se postará o přepsání této hodnoty v obslužné rutině události tak, aby tato hodnota byla prvkem, který vyvolal událost:
// použijte jQuery $("#btn1").click(function() ( alert(this.id); // jQuery zajistí, že "toto" je tlačítko ));
Jak jQuery dokáže změnit hodnotu tohoto? Přečtěte si níže.

Další dva způsoby: apply() a call() Je logické, že čím častěji funkce používáte, tím častěji je musíte předávat a volat v různých kontextech. Často je potřeba tuto hodnotu přepsat. Pokud si pamatujete, funkce v JavaScriptu jsou objekty. V praxi to znamená, že funkce mají předem definované metody. apply() a call() jsou dvě z nich. Umožňují vám přepsat tuto hodnotu:
var auto = ( rok: 2008, model: "Dodge Bailout" ); makeArray.apply(auto, [ "jeden", "dva" ]); // => [ auto, "jeden", "dva" ] makeArray.call(auto, "jedno", "dva"); // => [ auto, "jeden", "dva" ]
Tyto dvě metody jsou velmi podobné. První parametr toto přepíše. Rozdíly mezi nimi jsou v následujících argumentech: Function.apply() přijímá pole hodnot, které budou předány funkci, zatímco Function.call() přijímá argumenty samostatně. V praxi je podle mého názoru pohodlnější použít apply() .

Pravidlo #3 volání funkce: Pokud chcete přepsat hodnotu této hodnoty bez kopírování funkce do jiného objektu, můžete použít myFunction.apply(obj) nebo myFunction.call(obj) .

Konstruktory Nebudu se podrobně zabývat deklarováním vlastních typů v JavaScriptu, ale myslím, že je nutné připomenout, že v JavaScriptu nejsou žádné třídy a každý vlastní typ potřebuje konstruktor. Navíc je lepší deklarovat metody vlastního typu pomocí prototype , což je vlastnost funkce konstruktoru. Vytvořme si vlastní typ:
// deklarujte funkci konstruktoru ArrayMaker(arg1, arg2) ( this.someProperty = "nezáleží"; this.theArray = [ this, arg1, arg2 ]; ) // deklarujte metody ArrayMaker.prototype = ( someMethod: function () ( alert( "Voláno nějakou metodou" getArray: function () ( return this.theArray; ) ); var am = new ArrayMaker("jeden", "dva"); var other = new ArrayMaker("první", "druhý"); am.getArray(); // => [ am, "jeden", "dva" ]
Důležitá věc v tomto příkladu je přítomnost operátoru new před voláním funkce. Pokud by tomu tak nebylo, šlo by o globální volání a vlastnosti vytvořené v konstruktoru by patřily globálnímu objektu. To nepotřebujeme. Kromě toho konstruktory obvykle nevracejí hodnoty explicitně. Bez operátoru new by konstruktor vrátil undefined, s ním vrátí toto. Za dobrý styl se považuje pojmenovávat konstruktory velkým písmenem; To vám připomene potřebu nového operátora.

Jinak bude kód uvnitř konstruktoru pravděpodobně podobný kódu, který byste napsali v jiném jazyce. Hodnota tohoto je v tomto případě nový objekt, který vytváříte.

Volání funkce Pravidlo č. 4: Při volání funkce s operátorem new bude jeho hodnotou nový objekt vytvořený běhovým prostředím JavaScriptu. Pokud tato funkce nevrátí žádný objekt explicitně, bude vrácena implicitně.

Závěr Doufejme, že pochopení rozdílu mezi různými způsoby volání funkcí vám pomůže zlepšit váš kód JavaScript. Někdy je obtížné zachytit chyby související s touto hodnotou, takže má smysl jim předem předcházet.

Poslední aktualizace: 04.09.2018

Funkce jsou sada instrukcí, které provádějí konkrétní akci nebo vypočítají konkrétní hodnotu.

Syntaxe definice funkce:

Funkce název_funkce([parametr [, ...]])( // Pokyny )

Definice funkce začíná klíčovým slovem function následovaným názvem funkce. Název funkce se řídí stejnými pravidly jako název proměnné: může obsahovat pouze čísla, písmena, podtržítka a znaky dolaru ($) a musí začínat písmenem, podtržítkem nebo dolarem.

Za názvem funkce jsou parametry uvedeny v závorkách. I když funkce nemá žádné parametry, obsahuje pouze prázdné závorky. Poté ve složených závorkách přichází tělo funkce, které obsahuje sadu instrukcí.

Pojďme definovat nejjednodušší funkci:

Funkce display())( document.write("funkce v JavaScriptu"); )

Tato funkce se nazývá display(). Neakceptuje žádné parametry a vše, co dělá, je zapsání řetězce na webovou stránku.

Pouhé definování funkce však k jejímu fungování nestačí. Ještě jí musíte zavolat:

function display())( document.write("funkce v JavaScriptu"); ) display();

Není nutné dávat funkcím konkrétní název. Můžete použít anonymní funkce:

Var display = function())( // definice funkce document.write("funkce v JavaScriptu"); ) display();

To, co děláme, je ve skutečnosti definovat proměnnou zobrazení a přiřadit jí odkaz na funkci. A pak je funkce volána na základě názvu proměnné.

Můžeme také dynamicky přiřadit funkce proměnné:

Function goodMorning())( document.write("Dobré ráno"); ) function goodEvening())( document.write("Dobrý večer"); ) var message = goodMorning; zpráva(); // Dobré ráno zpráva = dobrýVečer; zpráva(); // Dobrý večer

Funkční parametry

Zvažme předávání parametrů:

Funkce display(x)( // definice funkce var z = x * x; document.write(x + "na druhou se rovná " + z); ) display(5); // volání funkce

Funkce zobrazení přebírá jeden parametr - x. Při volání funkce jí tedy můžeme předat hodnotu, například číslo 5, jako v tomto případě.

Pokud funkce přebírá několik parametrů, pak pomocí operátoru spread... můžeme předat sadu hodnot pro tyto parametry z pole:

Funkce sum(a, b, c)( nechť d = a + b + c; console.log(d); ) suma(1, 2, 3); nech čísla = ; součet(...čísla);

Ve druhém případě jsou funkci předána čísla z pole nums. Ale aby se přenášelo nejen pole jako jedna hodnota, ale čísla z tohoto pole, používá se operátor spread (elipsa...).

Volitelné parametry

Funkce může mít mnoho parametrů, ale některé nebo všechny parametry mohou být volitelné. Není-li pro parametry předána žádná hodnota, mají výchozí hodnotu „undefined“.

Funkce display(x, y)( if(y === nedefinováno) y = 5; if(x === nedefinováno) x = 8; nechť z = x * y; console.log(z); ) display() ; // 40 zobrazení(6); // 30 display(6, 4) // 24

Zde má funkce zobrazení dva parametry. Při volání funkce můžeme kontrolovat jejich hodnoty. Při volání funkce však není nutné předávat hodnoty těchto parametrů. Pro kontrolu přítomnosti hodnoty parametru se používá porovnání s nedefinovanou hodnotou.

Existuje další způsob, jak definovat výchozí hodnoty parametrů:

Funkce display(x = 5, y = 10)( nechť z = x * y; console.log(z); ) display(); // 50 zobrazení(6); // 60 display(6, 4) // 24

Pokud parametry x a y nejsou předány žádné hodnoty, získají se jako hodnoty čísel 5 a 10. Tato metoda je stručnější a intuitivnější než srovnávání s nedefinovanou.

V tomto případě lze odvodit výchozí hodnotu parametru představující výraz:

Funkce display(x = 5, y = 10 + x)( nechť z = x * y; console.log(z); ) display(); // 75 zobrazení(6); // 96 display(6, 4) // 24

V tomto případě závisí hodnota parametru y na hodnotě x.

V případě potřeby můžeme získat všechny předané parametry prostřednictvím globálně přístupného pole argumentů:

Funkce display())( var z = 1; for(var i=0; i [ okno, "jedna", "dva" ]
Počkejte. Odkud pochází objekt okna? Proč se to rovná oknu?

V JavaScriptu, bez ohledu na to, zda je skript spuštěn v prohlížeči nebo v jiném prostředí, je vždy definován globální objekt. Jakýkoli kód v našem skriptu, který není „vázán“ na nic (tj. mimo deklaraci objektu), je ve skutečnosti v kontextu globálního objektu. V našem případě není makeArray pouze funkcí, která „chodí“ sama o sobě. MakeArray je ve skutečnosti metoda okna globálního objektu (v případě spuštění kódu v prohlížeči). Je snadné dokázat:
alert(typeof window.methodThatNeexistuje); // => undefined alert(typeof window.makeArray); // => funkce
To znamená volání makeArray("jeden", "dva"); je ekvivalentní volání window.makeArray("jeden", "dva"); .

Je mi smutno, že je to nejběžnější způsob volání funkcí, protože to znamená přítomnost globální funkce. A všichni víme, že globální funkce a proměnné nejsou nejlepší formou v programování. To platí zejména pro JavaScript. Vyhněte se globálním definicím a nebudete litovat.

Pravidlo č. 1 volání funkce: Pokud je funkce volána přímo, bez určení objektu (například myFunction()), bude hodnota tohoto globálního objektu (okno, pokud je kód spuštěn v prohlížeči).

Volání metody Vytvořme jednoduchý objekt a udělejme z makeArray jeho metodu. Pojďme deklarovat objekt pomocí doslovného zápisu a pak zavolejte naši metodu:
// vytvoření objektu var arrayMaker = ( someProperty: "nějaká hodnota", make: makeArray ); // volání metody make() arrayMaker.make("jeden", "dva"); // => [ arrayMaker, "jeden", "dva" ] // alternativní syntaxe, použijte hranaté závorky arrayMaker["make"]("jeden", "dva"); // => [ arrayMaker, "jeden", "dva" ]
Vidíte ten rozdíl? Hodnota toho je v tomto případě samotný objekt. Proč ne window , jako v předchozím případě, protože deklarace funkce se nezměnila? Tajemství je v tom, jak jsou funkce předávány v JavaScriptu. Funkce je standardní typ JavaScriptu, který je ve skutečnosti objektem, a jako každý jiný objekt lze funkce předávat a kopírovat. V tomto případě jsme v podstatě zkopírovali celou funkci, včetně seznamu argumentů a těla, a přiřadili výsledný objekt vlastnosti make objektu arrayMaker. To je ekvivalentní tomuto prohlášení:
var arrayMaker = ( someProperty: "Nějaká hodnota"; make: function (arg1, arg2) ( return [ this, arg1, arg2]; ) );
Pravidlo #2 volání funkce: Ve funkci volané pomocí syntaxe volání metody, jako je obj.myFunction() nebo obj["myFunction"]() , bude mít hodnotu obj .

Nepochopení tohoto obecně jednoduchého principu často vede k chybám při zpracování událostí:
function buttonClicked())( var text = (toto === okno) ? "okno" : this.id; alert(text); ) var button1 = document.getElementById("btn1"); var button2 = document.getElementById("btn2"); button1.onclick = buttonClicked; button2.onclick = function())( buttonClicked(); );
Po kliknutí na první tlačítko se zobrazí zpráva "btn1" protože v tomto případě voláme funkci jako metodu a ta uvnitř funkce získá hodnotu objektu, ke kterému tato metoda patří. Kliknutím na druhé tlačítko se zobrazí "okno" protože v tomto případě voláme buttonClicked přímo (tj. ne jako obj.buttonClicked()). Totéž se stane, když tagu elementu přiřadíme handler události, jako v případě třetího tlačítka. Kliknutím na třetí tlačítko se zobrazí stejná zpráva jako na druhé.

Při používání knihoven jako jQuery na to nemusíte myslet. jQuery se postará o přepsání této hodnoty v obslužné rutině události tak, aby tato hodnota byla prvkem, který vyvolal událost:
// použijte jQuery $("#btn1").click(function() ( alert(this.id); // jQuery zajistí, že "toto" je tlačítko ));
Jak jQuery dokáže změnit hodnotu tohoto? Přečtěte si níže.

Další dva způsoby: apply() a call() Je logické, že čím častěji funkce používáte, tím častěji je musíte předávat a volat v různých kontextech. Často je potřeba tuto hodnotu přepsat. Pokud si pamatujete, funkce v JavaScriptu jsou objekty. V praxi to znamená, že funkce mají předem definované metody. apply() a call() jsou dvě z nich. Umožňují vám přepsat tuto hodnotu:
var auto = ( rok: 2008, model: "Dodge Bailout" ); makeArray.apply(auto, [ "jeden", "dva" ]); // => [ auto, "jeden", "dva" ] makeArray.call(auto, "jedno", "dva"); // => [ auto, "jeden", "dva" ]
Tyto dvě metody jsou velmi podobné. První parametr toto přepíše. Rozdíly mezi nimi jsou v následujících argumentech: Function.apply() přijímá pole hodnot, které budou předány funkci, zatímco Function.call() přijímá argumenty samostatně. V praxi je podle mého názoru pohodlnější použít apply() .

Pravidlo #3 volání funkce: Pokud chcete přepsat hodnotu této hodnoty bez kopírování funkce do jiného objektu, můžete použít myFunction.apply(obj) nebo myFunction.call(obj) .

Konstruktory Nebudu se podrobně zabývat deklarováním vlastních typů v JavaScriptu, ale myslím, že je nutné připomenout, že v JavaScriptu nejsou žádné třídy a každý vlastní typ potřebuje konstruktor. Navíc je lepší deklarovat metody vlastního typu pomocí prototype , což je vlastnost funkce konstruktoru. Vytvořme si vlastní typ:
// deklarujte funkci konstruktoru ArrayMaker(arg1, arg2) ( this.someProperty = "nezáleží"; this.theArray = [ this, arg1, arg2 ]; ) // deklarujte metody ArrayMaker.prototype = ( someMethod: function () ( alert( "Voláno nějakou metodou" getArray: function () ( return this.theArray; ) ); var am = new ArrayMaker("jeden", "dva"); var other = new ArrayMaker("první", "druhý"); am.getArray(); // => [ am, "jeden", "dva" ]
Důležitá věc v tomto příkladu je přítomnost operátoru new před voláním funkce. Pokud by tomu tak nebylo, šlo by o globální volání a vlastnosti vytvořené v konstruktoru by patřily globálnímu objektu. To nepotřebujeme. Kromě toho konstruktory obvykle nevracejí hodnoty explicitně. Bez operátoru new by konstruktor vrátil undefined, s ním vrátí toto. Za dobrý styl se považuje pojmenovávat konstruktory velkým písmenem; To vám připomene potřebu nového operátora.

Jinak bude kód uvnitř konstruktoru pravděpodobně podobný kódu, který byste napsali v jiném jazyce. Hodnota tohoto je v tomto případě nový objekt, který vytváříte.

Volání funkce Pravidlo č. 4: Při volání funkce s operátorem new bude jeho hodnotou nový objekt vytvořený běhovým prostředím JavaScriptu. Pokud tato funkce nevrátí žádný objekt explicitně, bude vrácena implicitně.

Závěr Doufejme, že pochopení rozdílu mezi různými způsoby volání funkcí vám pomůže zlepšit váš kód JavaScript. Někdy je obtížné zachytit chyby související s touto hodnotou, takže má smysl jim předem předcházet.

Dalším základním konceptem v kódování jsou funkce , které vám umožňují uložit část kódu, který provádí jeden úkol uvnitř definovaného bloku, a poté tento kód volat, kdykoli jej potřebujete, pomocí jediného krátkého příkazu – namísto toho, abyste museli zadávat stejný příkaz. kód vícekrát. V tomto článku prozkoumáme základní pojmy za funkcemi, jako je základní syntaxe, jak je vyvolávat a definovat, rozsah a parametry.

Předpoklady: Objektivní:
Základní počítačová gramotnost, základní znalost HTML a CSS, JavaScript první kroky.
Porozumět základním konceptům funkcí JavaScriptu.
Kde najdu funkce?

V JavaScriptu najdete funkce všude. Ve skutečnosti jsme funkce používali po celou dobu kurzu; jen jsme o nich moc nemluvili. Nyní je však čas, abychom začali mluvit o funkcích explicitně a skutečně prozkoumali jejich syntaxi.

V podstatě kdykoli použijete strukturu JavaScriptu, která obsahuje pár závorek - () - a nepoužíváte běžnou vestavěnou jazykovou strukturu, jako je smyčka for , smyčka while nebo do...while nebo if. ..else příkaz , používáte funkci.

Vestavěné funkce prohlížeče

V tomto kurzu jsme hodně využívali funkce zabudované v prohlížeči. Pokaždé, když jsme manipulovali s textovým řetězcem, například:

Var myText = "Jsem řetězec"; var newString = myText.replace("string", "klobása"); console.log(newString); // funkce řetězce replace() vezme řetězec, // nahradí jeden podřetězec jiným a vrátí // nový řetězec s provedenou náhradou

Nebo pokaždé, když manipulujeme s polem:

Var myArray = ["já", "láska", "čokoláda", "žáby"]; var madeAString = myArray.join(" "); console.log(madeAString); // funkce join() vezme pole, spojí // všechny položky pole dohromady do jediného // řetězce a vrátí tento nový řetězec

Nebo pokaždé, když jsme vygenerovali náhodné číslo:

Var myNumber = Math.random(); // funkce random() vygeneruje náhodné // číslo mezi 0 a 1 a vrátí toto // číslo

Použili jsme funkci!

Poznámka: Neváhejte a zadejte tyto řádky do konzole JavaScript vašeho prohlížeče, abyste se v případě potřeby znovu seznámili s jejich funkčností.

Jazyk JavaScript má mnoho vestavěných funkcí, které vám umožňují dělat užitečné věci, aniž byste museli celý kód psát sami. Ve skutečnosti některé kódy, které voláte, když vyvoláte (senzační slovo pro spuštění nebo spuštění) vestavěné funkce prohlížeče, nebylo možné napsat v JavaScriptu – mnoho z těchto funkcí volá části kódu prohlížeče na pozadí, který je napsán převážně v nízkoúrovňových systémových jazycích, jako je C++, nikoli ve webových jazycích, jako je JavaScript.

Mějte na paměti, že některé vestavěné funkce prohlížeče nejsou součástí základního jazyka JavaScript – některé jsou definovány jako součást rozhraní API prohlížeče, která staví na výchozím jazyce, aby poskytovala ještě více funkcí (viz první část našeho kurzu pro další popisy). Na používání rozhraní API prohlížeče se podíváme podrobněji v pozdějším modulu.

Funkce versus metody

Jedna věc, kterou si musíme vyjasnit, než budeme pokračovat – technicky vzato, vestavěné funkce prohlížeče nejsou funkce – jsou to metody. Zní to trochu děsivě a zmateně, ale nebojte se – slova funkce a metoda jsou v této fázi vašeho učení do značné míry zaměnitelná, alespoň pro naše účely.

Rozdíl je v tom, že metody jsou funkce definované uvnitř objektů. Vestavěné funkce prohlížeče (metody) a proměnné (které se nazývají vlastnosti ) jsou uloženy uvnitř strukturovaných objektů, aby byl kód efektivnější a snáze se s ním manipulovalo.

Zatím se nemusíte učit o vnitřním fungování strukturovaných objektů JavaScript – můžete počkat na náš pozdější modul, který vás naučí vše o vnitřním fungování objektů a jak si vytvořit vlastní. Prozatím jsme chtěli vyjasněte všechny možné záměny metody a funkce – pravděpodobně se setkáte s oběma termíny, když se podíváte na dostupné související zdroje na webu.

Vlastní funkce

V kurzu jste také zatím viděli spoustu vlastních funkcí – funkce definované ve vašem kódu, nikoli v prohlížeči. Kdykoli jste viděli vlastní název se závorkami přímo za ním, používali jste vlastní funkci. V našem náhodném V příkladu canvas-circles.html (viz také celý text ) z našeho článku o smyčkách jsme zahrnuli vlastní funkci draw(), která vypadala takto:

Funkce draw() ( ctx.clearRect(0,0,WIDTH,HEIGHT); for (var i = 0; i< 100; i++) { ctx.beginPath(); ctx.fillStyle = "rgba(255,0,0,0.5)"; ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); ctx.fill(); } }

Tato funkce nakreslí 100 náhodných kruhů do prvku. Pokaždé, když to chceme udělat, můžeme funkci jednoduše vyvolat tímto

než abychom museli celý ten kód vypisovat znovu pokaždé, když ho chceme opakovat. A funkce mohou obsahovat jakýkoli kód, který se vám líbí – můžete dokonce volat další funkce zevnitř funkcí. Výše uvedená funkce například třikrát volá funkci random(), která je definována následujícím kódem:

Funkce random(number) ( return Math.floor(Math.random()*number); )

Tuto funkci jsme potřebovali, protože funkce Math.random() vestavěná do prohlížeče generuje pouze náhodné desetinné číslo mezi 0 a 1. Chtěli jsme náhodné celé číslo mezi 0 a zadaným číslem.

Vyvolání funkcí

Pravděpodobně už v tom máte jasno, ale pro případ... abyste skutečně použili funkci poté, co byla definována, musíte ji spustit – nebo vyvolat –. To se provede vložením názvu funkce do kód někde následovaný závorkami.

Funkce myFunction() ( alert("ahoj"); ) myFunction() // volá funkci jednou

Anonymní funkce

Můžete vidět funkce definované a vyvolané mírně odlišnými způsoby. Zatím jsme právě vytvořili takovou funkci:

Funkce myFunction() ( alert("ahoj"); )

Ale můžete také vytvořit funkci, která nemá název:

Function() ( alert("ahoj"); )

Tomu se říká anonymní funkce – nemá jméno! Také to samo o sobě nic neudělá. Obecně používáte anonymní funkci spolu s obslužnou rutinou události, například následující spustí kód uvnitř funkce, kdykoli se klikne na související tlačítko:

Var myButton = document.querySelector("tlačítko"); myButton.onclick = function() ( alert("ahoj"); )

Výše uvedený příklad by vyžadoval, aby na stránce byl k dispozici prvek, který lze vybrat a kliknout. Tuto strukturu jste již v průběhu kurzu několikrát viděli a v dalším článku se o ní dozvíte více a uvidíte, jak se používá.

Anonymní funkci můžete také přiřadit jako hodnotu proměnné, například:

Var myGreeting = function() ( alert("ahoj"); )

Tuto funkci lze nyní vyvolat pomocí:

MyGreeting();

To efektivně dává funkci název; funkci můžete také přiřadit jako hodnotu více proměnných, například:

Var otherGreeting = function() ( alert("ahoj"); )

Tuto funkci lze nyní vyvolat pomocí kteréhokoli z nich

MyGreeting(); dalsiPozdrav();

Ale to by bylo jen matoucí, takže to nedělejte! Při vytváření funkcí je lepší držet se tohoto formuláře:

Funkce myGreeting() ( alert("ahoj"); )

Anonymní funkce budete používat hlavně ke spuštění zátěže kódu v reakci na spuštění události – jako je klepnutí na tlačítko – pomocí obsluhy události. Opět to vypadá asi takto:

MyButton.onclick = function() ( alert("hello"); // Mohu sem vložit tolik kódu, kolik chci )

Funkční parametry

Některé funkce vyžadují zadání parametrů, když je vyvoláváte – to jsou hodnoty, které musí být zahrnuty do závorek funkce, které potřebuje, aby správně fungovala.

Poznámka: Parametry se někdy nazývají argumenty, vlastnosti nebo dokonce atributy.

Například vestavěná funkce Math.random() v prohlížeči nevyžaduje žádné parametry. Při volání vždy vrací náhodné číslo mezi 0 a 1:

Var myNumber = Math.random();

Funkce string replace() vestavěná v prohlížeči však potřebuje dva parametry – podřetězec, který se má najít v hlavním řetězci, a podřetězec, kterým se má tento řetězec nahradit:

Var myText = "Jsem řetězec"; var newString = myText.replace("string", "klobása");

Poznámka: Pokud potřebujete zadat více parametrů, jsou odděleny čárkami.

Je třeba také poznamenat, že někdy jsou parametry volitelné - nemusíte je specifikovat. Pokud tak neučiníte, funkce obecně převezme nějaký druh výchozího chování. Například parametr funkce pole join() je volitelný:

Var myArray = ["já", "láska", "čokoláda", "žáby"]; var madeAString = myArray.join(" "); // vrátí "Miluji čokoládové žáby" var madeAString = myArray.join(); // vrátí "I,love,chocolate,frogs"

Pokud není zahrnut žádný parametr pro určení spojovacího/oddělovacího znaku, použije se ve výchozím nastavení čárka.

Rozsah funkcí a konflikty

Promluvme si trochu o rozsahu – velmi důležitý koncept při práci s funkcemi Když vytváříte funkci, proměnné a další věci definované uvnitř funkce jsou ve svém vlastním samostatném rozsahu, což znamená, že jsou uzamčeny ve svých vlastních oddělených oddílech. nedosažitelné zevnitř jiných funkcí nebo z kódu mimo funkce.

Nejvyšší úroveň mimo všechny vaše funkce se nazývá globální rozsah. Hodnoty definované v globálním rozsahu jsou dostupné odkudkoli v kódu.

JavaScript je takto nastaven z různých důvodů – ale hlavně kvůli bezpečnosti a organizaci. Někdy nechcete, aby proměnné byly přístupné odkudkoli v kódu – externí skripty, které voláte odjinud, by se mohly začít s vaším kódem potýkat a způsobit problémy, protože náhodou používají stejné názvy proměnných jako jiné části kódu , což může způsobit konflikty.

Řekněme například, že máte soubor HTML, který volá dva externí soubory JavaScriptu a oba mají definovanou proměnnou a funkci, které používají stejný název:

pozdrav(); // first.js var name = "Chris"; function greeting() ( alert("Dobrý den " + jméno + ": vítejte v naší společnosti."); ) // second.js var name = "Zaptec"; funkce pozdrav() ( alert("Naše společnost se jmenuje " + jméno + "."); )

Obě funkce, které chcete volat, se nazývají greeting() , ale vždy můžete přistupovat pouze k funkci greeting() souboru second.js – je aplikována na HTML později ve zdrojovém kódu, takže její proměnná a funkce přepisují ty v first.js .

Uchovávání částí kódu uzamčených ve funkcích takovým problémům předchází a je považováno za nejlepší postup.

Je to trochu jako zoologická zahrada. Lvi, zebry, tygři a tučňáci jsou drženi ve svých vlastních výbězích a mají přístup pouze k věcem uvnitř výběhů – stejným způsobem jako rozsahy funkcí. Pokud by se dokázali dostat do jiných výběhů, nastaly by problémy. V nejlepším případě by se různá zvířata cítila v neznámém prostředí opravdu nepříjemně - lev nebo tygr by se uvnitř vodní, ledové oblasti tučňáků cítili hrozně. V nejhorším případě by se lvi a tygři mohli pokusit tučňáky sežrat!

Ošetřovatel zoo je jako globální působnost – má klíče ke vstupu do každého výběhu, k doplnění zásob potravy, ošetřování nemocných zvířat atd.

Aktivní učení: Hra s rozsahem

Podívejme se na skutečný příklad pro demonstraci rozsahu.

  • Nejprve vytvořte místní kopii našeho příkladu function-scope.html. Obsahuje dvě funkce zvané a() a b() a tři proměnné - x, y a z - z nichž dvě jsou definovány uvnitř funkcí a jedna v globálním rozsahu. Obsahuje také třetí funkci nazvanou output() , která přebírá jeden parametr a zobrazuje jej v odstavci na stránce.
  • Otevřete příklad v prohlížeči a v textovém editoru.
  • Otevřete konzolu JavaScriptu ve vývojářských nástrojích prohlížeče. V konzole JavaScriptu zadejte následující příkaz: output(x);
  • Měli byste vidět hodnotu proměnné x výstup na obrazovku.
  • Nyní zkuste zadat následující do výstupu konzoly (y); výstup(z);
  • Oba by měly vrátit chybu ve smyslu "ReferenceError: y není definováno". proč tomu tak je? Kvůli rozsahu funkcí - y a z jsou uzamčeny uvnitř funkcí a() a b(), takže výstup () k nim nemůže přistupovat, když je volán z globálního rozsahu.
  • Ale co když je volána z jiné funkce? Zkuste upravit a() a b(), aby vypadaly takto: funkce a() ( var y = 2; výstup(y); ) funkce b() ( var z = 3 output(z) Uložte kód a znovu jej načtěte do prohlížeče, poté zkuste zavolat funkce a() a b() z konzole JavaScriptu: a(); Funguje to dobře, protože funkce output() je volána uvnitř ostatních funkcí - ve stejném rozsahu, v jakém jsou definovány proměnné, ve kterých se tiskne, v každém případě je samotný výstup() dostupný odkudkoli, jak je definován v globálním rozsahu.
  • Nyní zkuste aktualizovat svůj kód takto: function a() (var y = 2; output(x); ) function b() (var z = 3; output(x); ) Uložte a znovu načtěte a zkuste to znovu v vaše konzole JavaScript:
  • A(); b();


  • 
    Reklama na webu