Funkce šipky Js. O klíčovém slově JavaScript „toto“: funkce použití s ​​vysvětlením. Pravidla pro používání funkcí šipek

Staly se velmi módními, vidíme je ve všech nových článcích. A pokud na ně nejste zvyklí, těžko pochopíte moderní (ES6) kód obsahující funkce šipek.

Tento článek není určen k tomu, aby vám řekl, kdy nebo jak je používat. Jen se pokusím vysvětlit novou syntaxi pro ty, kteří ji vidí poprvé. Jestli to využijete nebo ne, není důležité, ale dříve nebo později se s tím stejně někde setkáte. Je tedy lepší porozumět mechanismu této nové syntaxe.

Zde je malý příklad:

Const addOne = function(n) ( return n + 1; )

Výše uvedený kód lze zapsat takto:

Const addOne = (n) => ( návrat n + 1; )

Nebo v v tomto případě, ještě kratší:

Const addJedna = (n) => n + 1;

Druhý příklad používá ( ... ) složené závorky, ale protože se jedná pouze o jeden řádek kódu, lze složené závorky vynechat a návrat je implikován, jak je vidět ve třetím příkladu.

Jeden parametr

Když má funkce šipky jeden parametr, závorky lze vynechat:

// Bylo: someCallBack((results) => ( ... )) // Now: someCallBack(results => ( ... ))

Pokud však neexistují žádné parametry, musíte použít otevírací a uzavírací závorky:

SomeCallBack(() => ( ... ))

Funkce zpětného volání

Funkční šipky jsou užitečné zejména pro zpětná volání. Ti, kteří jsou obeznámeni s JavaScriptem, jsou obeznámeni s jeho lexikálním rozsahem, který je docela úhledný, ale umí dělat takové triky ( tento):

Var_this = toto; someCallBack(function() ( _this.accessOuterScope(); ))

Existuje několik variant tohoto „_toto“ (jako „já“ nebo „tamto“), ale myšlenka je stejná. Ve funkcích zpětného volání potřebujeme přístup k verzi vnějšího rozsahu, ale myšlenka je stejná. Ve funkcích zpětného volání potřebujeme přístup k verzi tohoto , která je nyní jiná než dříve, protože mluvíme o funkci zpětného volání.

Používáním funkce šipky, dostaneme "blokový rozsah" a "toto", což je v obou případech stejné "toto". To znamená, že výše uvedený kód lze přepsat bez _this = this:

SomeCallBack(() => ( this.accessOuterScope(); ))

"Obal"

Představme si situaci jako v Reactu, kde se event při kliknutí by měl volat doSomething() , (), ale měl by také předat argumenty funkci doSomething() (např. ID). Tento příklad ve skutečnosti nefunguje:

Nějaký uživatel)))

Kód se spustí, ale technicky zavolá doSomething() okamžitě po načtení stránky. K vyřešení tohoto problému se někteří vývojáři odvolávají na funkci wrapper:

Const User = React.createClass(function() ( render: function() ( return Some user), onClick: function() ( doSomething(this.props.userId); ) ))

Absence závorky v this.onClick znamená, že se jedná spíše o odkaz na funkci než o volání funkce.

Funkce onClick() je nyní něco jako obal pro doSomething() . Pomocí funkcí šipek můžete vytvořit „obaly“ tohoto typu:

Const User = React.createClass(function() ( render: function() ( return doSomething(this.props.userId))>Nějaký uživatel ) ))

Jako alternativu bychom také mohli použít .bind() , které nevyžaduje žádné obaly (funkce šipek nebo cokoliv):

Const User = React.createClass(function() ( render: function() ( return Some user ) ))

Podpora prohlížeče pro funkce šipek

Pokud potřebujete jinou podporu prohlížeče než nejnovější verze Chrome A Firefox, použití Babel transpiler pro převod kódu ES6, který jste napsali, na ES5.

ES6 má nový způsob vytváření funkcí – pomocí operátoru Arrow =>. Takové funkce se nazývají funkce šipky. Nabízejí kompaktnější syntaxi. Nemají jméno a pracují s tím jinak.

První věc, kterou uděláme, je spuštění skriptu Babel, který bude sledovat soubory a vytvářet nové verze, když se změní.

Otevřete složku projektu v příkazový řádek(KS). Zadejte příkaz:

A stiskněte Enter

Ve složce src vytvoříme soubor arr.js a ihned jej označíme v souboru index.html

</script>

Nejnovější verze prohlížečů podporují funkce šipek bez transpilace a můj prohlížeč je jednou z nich.

Napišme funkci, která sečte dvě čísla a vrátí jejich součet. Zavolejte funkci add .

Funkce add (x, y) ( return x + y; ) console.log (add (3, 6));

V konzoli uvidíme výsledek - 9

Nyní převedeme tuto funkci na funkci šipky.

Odeberme slovo funkce , odstraníme název funkce a složené závorky a slovo - return . Za parametry dáme šipku.

Nechť sečte = (x, y) => x + y; console.log(add(4, 6));

Pokud se podíváte na typ proměnné add pomocí operátoru typeof:

Console.log(typeof(add));

To je to, co uvidíme ve funkční konzoli

To znamená, že funkce šipek jsou běžné funkce. A můžete si to ověřit pohledem na transpilovaný kód.

"použít přísné"; var _typeof = typeof Symbol === "funkce" && typeof Symbol.iterator === "symbol" ? function (obj) ( return typeof obj; ) : function (obj) ( return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj ; var add = funkce add(x, y) ( return x + y; ); console.log(add(4, 6)); console.log(typeof add === "undefined" ? "undefined" : _typeof(add));

Vidíme, že Babel přeměnil náš kód na jednoduchý funkční výraz.

Napišme jednoduchou funkci, která odmocní dané číslo.

Nechť sečte = (x, y) => x + y; console.log(add(4, 6)); console.log(typeof(add)); let square = function(a) ( return a * a; ) console.log(square (4));

Podívejme se do konzole:

Funkce šipky bude vypadat takto:

Nechť čtverec = x => x * x;

Pokud má funkce šipky pouze jeden parametr, není nutné jej uzavírat do závorek!

Pojďme napsat funkci, která nebere vůbec žádné parametry.

Funkce givNumer () ( return 33; ) console.log(givNumer ());

Tato funkce jednoduše vytiskne číslo 33 do konzole:

Nechť givNumer = () => 33; console.log(givNumer());

Vytvořme funkci, která nebude nic vracet. Jednoduše zobrazí zprávu v konzole prohlížeče.

Nechat log = funkce () ( console.log("Ahoj světe!"); ); log();

Přepínač:

Nechat log = () => console.log("Ahoj světe!!!"); log();

Vytvořme funkci, jejíž tělo se bude skládat ze dvou čar.

Funkce bude mít dva parametry. Vytvořme proměnnou v těle funkce. Poté vrátíme výsledek.

Nechť mult = funkce (a, b) ( nechť výsledek = a * b; vrátí výsledek; ) console.log(mult (4, 5));

Pokud je ve funkci šipky několik řádků, jsou vyžadovány složené závorky - ()! A nezapomeňte definovat, co tato funkce vrací, pomocí klíčového slova return

Přepínač:

Nechť mult = (a, b) => ( nechť výsledek = a * b; vrátí výsledek; ) console.log(mult (4, 5));

Nyní vytvoříme funkci, která vrátí objektový literál:

Nechť literal = funkce () ( return ( jméno: "John"); ) console.log (literal ());

V konzoli uvidíme:

Nyní se pokusíme vytvořit funkci šipky, která vrátí objektový literál.

Je třeba mít na paměti, že pokud funkce šipky vrací objektový literál, jsou potřeba závorky - ()

Funkce šipky vracející objektový literál:

Nechť literál = () => ((jméno: "Jan")); console.log(literal());

Nyní zkusme použít funkci šipky jako IIFE - Immediately-invoked function expression

Ve zkratce jde o funkci, která se provede ihned po deklaraci

Vypadá to takto:

(funkce () ( console.log("IIFE"); ))();

Funkce arrow IIFE bude vypadat takto:

(() => console.log("IIFE"))();

Důležitou vlastností funkcí šipky je, že šipka musí následovat bezprostředně za parametry!

Nemůžete to prostě vzít a přesunout o řádek níže. Oznámí to chybu!

Praktická aplikace funkcí šipek. Šipkové funkce jsou velmi vhodné pro použití s ​​poli.

Vytvořme pole s nějakými čísly a nazvěme ho čísla . Myslím, že víte, že pole mají užitečné metody, které vám umožňují iterovat polem, filtrovat jej atd.

Vypočítejme součet všech proměnných pole. K tomu deklaruji další proměnnou - nechť suma = 0;

Použijme metodu forEach(), kterou má každé pole, budeme iterovat prvky a přičítat k součtu.

Nechť čísla = ; nechť součet = 0; čísla.proKaždou(funkce(číslo) ( součet += číslo; )); console.log(součet);

V konzoli uvidíme 55. Udělejme z této funkce funkci šipky: cisla.forEach(num => suma += num); console.log(součet);

Takže to, co nám dříve trvalo tři řádky, nyní trvá jeden.

Můžeme také odmocnit každý prvek pole.

Nechť na druhou = čísla.map(n => n * n); console.log(squared);

Funkce šipek a toto . K tomu si vytvořím objektový literál, který uložím do proměnné osoba.

Objekt person bude mít vlastnost name s hodnotou 'Bob' a vlastnost greet s hodnotou 'Greet' Pozdrav vytiskneme na konzoli a také se podíváme na účel tohoto .

Nechte osobu = ( jméno: "Bob", pozdrav: funkce () ( console.log("Dobrý den! Jmenuji se " + toto.jméno); console.log(toto; ) ); osoba.pozdrav();

V konzole prohlížeče uvidíme pozdrav a samotný objekt osoby.

Nyní nahradíme funkci šipkou a uvidíme, co se s tím stane.

Nechte osobu = ( jméno: "Bob", pozdrav: () => ( console.log("Dobrý den! Jmenuji se " + this.name); console.log(this; ) ); osoba.pozdrav();

Nyní jsme nezískali hodnotu názvu a hodnota tohoto je okno!

Ale proč? Jde o to, že hodnota tohoto je převzata z kontextu, ve kterém je funkce deklarována. ! Bez ohledu na to, kde bude tato funkce vykonávána. To je vidět na obrázku:

Máme program.

Zatím v něm není nic kromě objektu okna. Přidán objekt osoby. Všimněte si, že pro metodu používáme funkci šipky. Jak jsme řekli, hodnotu to budeme brát z kontextu. Kontext je prostředí. V tomto případě bude prostředí objektu osoby, všechny jeho vlastnosti a metody objekt okna. A pokud je hodnota tohoto převzata z kontextu, bude to odkazovat na objekt okna.

Pokud se podíváme na regulární funkci, pak víme, že se vztahuje k samotnému objektu osoby. Můžete se ptát, proč je hodnota tohoto ve funkcích šipek převzata z kontextu? A odpověď je velmi jednoduchá – udělali to tak! :-) Jde o to, že funkce šipek byly vytvořeny pro řešení problémů v jiné situaci. Podívejme se na příklad. Abychom problém viděli, vrátíme se k naší funkci šipky.

Nechte osobu = ( jméno: "Bob", pozdrav: function () ( console.log("Dobrý den! Jmenuji se " + this.name); console.log(this; ) );

Představme si, že náš Bob je dost zaneprázdněný a potřebuje pár sekund na dokončení své práce. Počkejte 2 sekundy. simulujeme pomocí funkce setTimeout(); .Tato funkce má jako první parametr funkci a jako druhý parametr počet milisekund čekání.

Nechte osobu = ( jméno: "Bob", pozdrav: funkce () ( setTimeout(funkce () ( console.log("Ahoj! Jmenuji se " + this.name); console.log(this); ), 2000) )); osoba.pozdrav();

Pokud máte zkušenosti s JavaScriptem, pak myslím, že chápete, v čem je problém. Každopádně se podívejme, co se bude dít v prohlížeči. Přesně o dvě sekundy později uvidíme tento obrázek v prohlížeči.

Ale proč? Pokud se podíváte na náš kód, je logické předpokládat. že to odkazuje na objekt person, protože používáme běžnou funkci. Jde o to, že setTimeout() patří objektu okna. Pokud to napíšete takto: window.setTimeout() , tak co si myslíte, že to znamená? A v konzoli dostaneme stejný výsledek! Existuje několik způsobů, jak tento problém vyřešit v ES5. Podíváme se na tu nejběžnější: Před setTimeout() deklaruji jinou proměnnou a přiřadím tuto jako hodnotu. A nyní v těle funkce místo tohoto označíme toto.

Nechte osobu = ( jméno: "Bob", pozdrav: funkce () ( nechť to = toto; setTimeout(funkce () ( console.log("Dobrý den! Jmenuji se " + tamto.jméno); console.log(to) , 2000); osoba.pozdrav();

Nyní díky uzavření bude mít funkce, kterou odešleme do setTimeout(), přístup k proměnné that, jejíž hodnota bude this , tedy v tomto případě objekt person.

Pro přehlednost se můžete podívat na to, co naše to a toto odkazují.

Nechte osobu = ( jméno: "Bob", pozdrav: funkce () ( nechť tamto = toto; setTimeout(funkce () ( console.log("Dobrý den! Jmenuji se " + tamto.jméno); console.log("It is my That = " + that); console.log("It is my This = " + this); ), 2000); ) ); osoba.pozdrav();

V konzoli uvidíme potvrzení:

Vidíme, že toto bude objekt okna - This = , a to bude objekt naší osoby - That = .

V ES6 můžeme k vyřešení tohoto problému jednoduše použít funkci šipky.

Nechte osobu = ( jméno: "Bob", pozdrav: funkce () ( setTimeout(() => ( console.log("Ahoj! Jmenuji se " + this.name); console.log("To je moje toto = " + toto); ), 2000); )); osoba.pozdrav();

V důsledku toho uvidíme v konzole:

V grafický příklad pro funkci šipky bude kontextem objekt osoby, nikoli objekt okna. proto se to bude týkat osoby.

Kromě kompaktní syntaxe byly pro řešení problémů, jako jsou tyto, zavedeny funkce šipek.

Pro informaci se můžete podívat, jak to Babel vyřešil

Var osoba = ( jméno: "Bob", pozdrav: funkce pozdrav() ( var _this = toto; setTimeout(funkce () ( console.log("Ahoj! Jmenuji se " + _this.name); console.log(" Je to moje Toto = " + _this); ), 2000); )); osoba.pozdrav(); Babel použil stejnou metodu, jakou jsme použili v ES5. Jediný rozdíl je v tom, že jsme proměnnou nazvali that, a Babel ji nazval - _this. Díky uzavření bude mít funkce, kterou odešleme do setTimeout, přístup k proměnné _this a v důsledku toho k objektu person.

Myslím, že nejtěžší částí této části je pochopit, jak uzávěry fungují.

Některé další funkce funkcí šipek:
Více informací o ES6 a funkcích šipek můžete vidět v mém příspěvku

Ahoj všichni! V tomto článku se podíváme na to, jaké funkce šipek jsou v ES6 a jak je používat.

Šipkové funkce jsou funkce, které se zapisují pomocí operátoru šipky (=>).

Podívejme se hned na příklad:

Nechť sečte = (x, y) => x + y;
console.log(add(5, 2));

V důsledku provedení této funkce uvidíme v konzole číslo 7.

Nejprve předáme argumenty v závorkách, poté vložíme znaménko šipky a poté zapíšeme kód samotné funkce. V našem případě jednoduše vezme dvě čísla a sečte je. Teoreticky je to stejné jako vyjádření funkce v ES5. Pokud používáte Babel nebo podobné kompilátory, pravděpodobně napíší něco takového:

Var add = funkce add(x, y) (
návrat x + y;
};

Pokud vaše funkce přebírá pouze jeden parametr, jsou závorky volitelné.

Nechť čtverec = x => x*x;

Tato funkce bere pouze jeden argument a odmocňuje dané číslo.

Funkce bez parametrů:

Nechť func = () => 77;

Pokud vaše funkce obsahuje několik řádků, musíte za prvé použít složené závorky a za druhé nezapomeňte napsat, co funkce vrací, tj. použijte klíčové slovo return.

Nechte vynásobit = (x, y) => (
nech výsledek = x*y;
vrátit výsledek;
};

Pokud potřebujete vrátit objektový literál, musíte jej zabalit do závorek:

Nechť getObject = () => (( značka: "BMW" ));

Samovolná funkce vypadá takto:

Výraz funkce šipky je syntakticky kompaktní alternativou k výrazu regulární funkce , i když nemá vlastní vazby na klíčová slova this , arguments , super nebo new.target. Výrazy funkce šipky se jako metody nehodí a nelze je použít jako konstruktory.

Syntaxe Základní syntaxe (param1, param2, …, paramN) => ( příkazy ) (param1, param2, …, paramN) => výraz // ekvivalentní k: => ( návratový výraz; ) // Závorky jsou volitelné, pokud je název pouze jednoho parametru: (singleParam) => ( commands ) singleParam => ( statement ) // Seznam parametrů pro funkci bez parametrů by měl být zapsán s párem závorek () => ( commands ) Pokročilá syntaxe // Parenthesize tělo funkce pro vrácení objektového doslovného výrazu: params => ((foo: bar)) // Parametry zbytku a výchozí parametry jsou podporovány (param1, param2, ...rest) => ( příkazy ) (param1 = defaultValue1 , param2, …, paramN = defaultValueN) => ( statement ) // Destrukturalizace v rámci seznamu parametrů je také podporována var f = ( = , (x: c) = (x: a + b)) => a + b + c; // 6 Popis

Zavedení funkcí šipek ovlivnily dva faktory: potřeba kratších funkcí a chování klíčového slova this.

Kratší funkce var prvky = [ "Vodík", "Helium", "Lithium", "Beryllium" ]; // Tento příkaz vrátí pole: elements.map (function(element) ( return element.length; )); // Regulární funkci výše lze zapsat jako funkci šipky pod elements.map((element) => ( return element.length; )); // // Když existuje pouze jeden parametr, můžeme odstranit okolní závorky elements.map (element => ( return element.length; )); // // Když je jediným příkazem ve funkci šipky `return`, můžeme odstranit `return` a odstranit // okolní složené závorky elements.map(element => element.length); // // V tomto případě, protože potřebujeme pouze vlastnost length, můžeme použít destrukční parametr: // Všimněte si, že `length` odpovídá vlastnosti, kterou chceme získat, zatímco // zjevně nespeciální `lengthFooBArX` je pouze název proměnné, kterou lze // změnit na libovolný platný název proměnné, který chcete elements.map (((length:lengthFooBArX )) => lengthFooBArX); // // Toto přiřazení destrukčního parametru lze také zapsat, jak je vidět níže. Všimněte si však, že v // tomto příkladu nepřiřazujeme hodnotu `length` k vlastnosti made up. Místo toho se jako vlastnost, kterou chceme z objektu načíst, použije samotný doslovný název // proměnné `délka`. elementy.map ((( délka )) => délka); // Neoddělujte to

Před funkcemi šipky každá nová funkce definovala svou vlastní tuto hodnotu na základě toho, jak byla funkce volána:

  • Nový objekt v případě konstruktoru.
  • nedefinováno ve volání funkcí přísného režimu.
  • Základní objekt, pokud byla funkce volána jako "metoda objektu".

To se ukázalo jako méně než ideální s objektově orientovaným stylem programování.

Funkce Person() ( // Konstruktor Person() definuje `this` jako instanci sebe sama. this.age = 0; setInterval(function growUp() ( // V nepřísném režimu definuje funkce growUp() ` this` // jako globální objekt (protože je to místo, kde se provádí growUp().), // který se liší od `this` // definovaného konstruktorem Person(). this.age++; ), 1000) ) var p = nová osoba();

V ECMAScriptu 3/5 byl tento problém opravitelný přiřazením hodnoty v tomto proměnné, kterou lze uzavřít.

Funkce Osoba() ( var that = this; that.age = 0; setInterval(function growUp() ( // Zpětné volání odkazuje na proměnnou `that`, jejíž // hodnota je očekávaný objekt. that.age++; ) , 1000) "použít přísné"; var obj = (a: 10); Object.defineProperty(obj, "b", ( get: () => ( console.log(this.a, typeof this.a, this); // undefined "undefined" Window (...) (nebo globální object) return this.a + 10 // představuje globální objekt "Window", proto "this.a" vrátí "undefined" ) ));

Použití nového operátora

Funkce šipek nelze použít jako konstruktory a při použití s ​​novým souborem vyvolá chybu.

Var Foo = () => (); var foo = new Foo(); // TypeError: Foo není konstruktor

Použití vlastnosti prototypu

Funkce šipek nemají vlastnost prototypu.

Var Foo = () => (); console.log(Foo.prototype); // nedefinováno

Použití klíčového slova výnos

Klíčové slovo výnos nesmí být použito v těle funkce šipky (s výjimkou případů, kdy je to povoleno v rámci funkcí dále vnořených do ní). V důsledku toho nelze funkce šipek použít jako generátory.

Funkční tělo

Funkce šipek mohou mít buď „stručné tělo“ nebo obvyklé „blokové tělo“.

Ve stručném těle je zadán pouze výraz, který se stává implicitní návratovou hodnotou. V těle bloku musíte použít explicitní příkaz return.

Var func = x => x * x; // stručná syntaxe těla, implikovaný "return" var func = (x, y) => ( return x + y; ); // s tělem bloku, je potřeba explicitní "return".

Vrácení objektových literálů

Mějte na paměti, že vracení objektových literálů pomocí stručných parametrů syntaxe těla => (object:literal) nebude fungovat podle očekávání.

Var func = () => ( foo: 1 ); // Volání funkce func() vrací hodnotu undefined! var func = () => ( foo: function() () ); // SyntaxError: příkaz funkce vyžaduje název

Je to proto, že kód uvnitř složených závorek (()) je analyzován jako sekvence příkazů (tj. s foo se zachází jako se štítkem, nikoli s klíčem v objektovém literálu).

Doslovný objekt musíte zabalit do závorek:

Var func = () => (( foo: 1 ));

Konce řádků

Funkce šipky nemůže obsahovat zalomení řádku mezi svými parametry a šipkou.

Var func = (a, b, c) => 1; // SyntaxError: očekávaný výraz, dostal "=>"

To však lze upravit vložením konce řádku za šipku nebo použitím závorek/složených závorek, jak je vidět níže, abyste zajistili, že kód zůstane pěkný a nadýchaný. Mezi argumenty můžete také vkládat konce řádků.

Var func = (a, b, c) => 1; var func = (a, b, c) => (1); var func = (a, b, c) => ( return 1 ); var func = (a, b, c) => 1; // nebyla vyvolána žádná SyntaxError

Pořadí analýzy

Přestože šipka ve funkci šipky není operátor, funkce šipky mají speciální pravidla analýzy, která reagují s prioritou operátorů odlišně ve srovnání s běžnými funkcemi.

Nechte zpětné volání; zpětné volání = zpětné volání || funkce(); // ok zpětné volání = zpětné volání || () => (); // SyntaxError: neplatné argumenty funkce šipka callback = zpětné volání || (() => ()); // OK

Další příklady // Funkce prázdné šipky vrací hodnotu undefined let empty = () => (); (() => "foobar")(); // Vrátí "foobar" // (toto je výraz okamžitě vyvolané funkce) var simple = a => a > 15 ? 15: a; jednoduchý(16); // 15 simple(10); // 10 nechť max = (a, b) => a > b ? a: b; // Snadné filtrování polí, mapování, ... var arr = ; var sum = arr.reduce((a, b) => a + b); // 66 var sudá = arr.filter(v => v % 2 == 0); // var double = arr.map(v => v * 2); // // Výstižnější řetězce slibů slib.then(a => ( // ... )).then(b => ( // ... )); // Bezparametrické funkce šipek, které lze vizuálně snadněji analyzovat setTimeout(() => ( console.log("Stanu se dříve"); setTimeout(() => ( // hlubší kód console.log("Stanu se později") ; ), jedenáct); Specifikace Specifikace Stav Komentář
ECMAScript 2015 (6. vydání, ECMA-262)
Standard Počáteční definice.
ECMAScript nejnovější koncept (ECMA-262)
Definice "definice funkcí šipky" v této specifikaci.
Návrh
Kompatibilita s prohlížečem

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

Aktualizujte údaje o kompatibilitě na GitHubu

Desktop Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Webové zobrazení Android Chrome pro Android Firefox pro Android Opera pro Android Safari na iOS Samsung Internet Node.jsFunkce šipek Koncová čárka v parametrech
Plná podpora Chrome 45Plná podpora Edge AnoPlná podpora Firefoxu 22

Poznámky

Plná podpora 22

Poznámky

Poznámky Před Firefoxem 39 byl za argumenty funkce šipky nesprávně povolen zakončovací znak řádku (\n). Toto bylo opraveno, aby odpovídalo specifikaci ES2015 a kódu jako () \n =>
IE Žádná podpora NeOpera plná podpora 32Safari Plná podpora 10WebView Plná podpora Androidu 45Chrome Plná podpora Androidu 45Firefox Plná podpora pro Android 22

Poznámky

Plná podpora 22

Poznámky

Poznámky Počáteční implementace funkcí šipek ve Firefoxu je automaticky zpřísnila. To bylo změněno od Firefoxu 24. Použití "use strict"; je nyní vyžadováno. Poznámky Před Firefoxem 39 byl za argumenty funkce šipky nesprávně povolen zakončovací znak řádku (\n). Toto bylo opraveno, aby odpovídalo specifikaci ES2015 a kód jako () \n => () nyní v této a novějších verzích vyvolá chybu SyntaxError.
Opera Android Plná podpora 32Safari iOS Plná podpora 10Samsung Internet Android Plná podpora 5.0nodejs Plná podpora Ano
Plná podpora Chrome 58Okraj?Plná podpora Firefoxu 52IE Žádná podpora NeOpera plná podpora 45Safari?WebView Plná podpora Androidu 58Chrome Plná podpora Androidu 58Firefox Plná podpora pro Android 52Opera Android Plná podpora 43Safari iOS?Samsung Internet Android Plná podpora 7.0nodejs Plná podpora Ano
Legenda Plná podpora Plná podpora Žádná podpora Žádná podpora Kompatibilita neznámá Kompatibilita neznámá Viz poznámky k implementaci. Viz poznámky k implementaci.
  • Tutorial

Jednou z nejzajímavějších částí nového standardu ECMAScript 6 jsou funkce šipek. Funkce šipek, jak název napovídá, jsou definovány novou syntaxí, která používá šipku => . Kromě vynikající syntaxe se však funkce šipek od tradičních funkcí liší ještě v dalších ohledech:

  • Lexikální vazba. Hodnoty speciální proměnné argumenty this , super a argumenty nejsou určeny tím, jak byly funkce šipky volány, ale tím, jak byly vytvořeny.
  • Neměnné toto , super a argumenty . Hodnoty těchto proměnných uvnitř funkcí šipek zůstávají po celou dobu nezměněny životní cyklus funkcí.
  • Funkce šipek nelze použít jako konstruktor a při použití s ​​operátorem new vyvolá chybu.
  • Nedostupnost „nativní“ hodnoty proměnné argumenty.
Důvodů pro zavedení těchto rozdílů bylo několik. První je, že vazba se v JavaScriptu používá poměrně často. Při použití tradičních funkcí je velmi snadné ztratit správnou tuto hodnotu, což může vést k neočekávaným následkům. Dalším důvodem je, že motory JS budou díky těmto omezením schopny snadno optimalizovat provádění funkcí šipek (na rozdíl od tradičních funkcí, které lze použít jako konstruktor a lze je volně upravovat speciální proměnné).


Poznámka: Tento článek je kompilací volného překladu článku Porozumění funkcím šipek ECMAScript 6 a čtení nejnovějšího návrhu specifikace (20. ledna 2014 Draft Rev 22).

Syntaxe Obecně syntaxe funkcí šipek vypadá takto:

Var fun = (x) => x;
Je velmi podobná podobné syntaxi v jazycích jako Scala, CoffeeScript a syntaxi lambda výrazů z C#.

Syntaxe funkcí šipek se může lišit v závislosti na tom, jak funkci deklarujete. Deklarace vždy začíná seznamem argumentů, za nimiž následuje šipka a tělo funkce. Seznam argumentů i tělo funkce mohou mít různé formy v závislosti na tom, co píšete.

Jeden parametr Deklarování funkce šipky, která vezme jeden argument a jednoduše jej vrátí, je velmi jednoduché:

Var Reflect = hodnota => hodnota; // ekvivalentní k var reflect = function(value) ( ​​vrácená hodnota; )
Když má funkce šipky pouze jeden argument, lze ji deklarovat bez závorek. Tělo funkce za šipkou také nemusí mít složené závorky a nemusí obsahovat klíčové slovo return.

Více parametrů Pokud však chcete deklarovat více než jeden parametr, musíte seznam parametrů uzavřít do závorek:

Var sum = (num1, num2) => num1 + num2; // ekvivalent var sum = function(num1, num2) ( return num1 + num2; );
Funkce součtu jednoduše přidá dva argumenty. Jediný rozdíl oproti předchozímu příkladu je přítomnost závorek a čárky (stejně jako u tradičních funkcí).

Žádné parametry Podobně funkce bez jakýchkoli argumentů musí mít prázdný seznam parametrů uzavřený v závorkách:

Var součet = () => 1 + 2; // ekvivalent var sum = function() ( return 1 + 2; );

Tradiční syntaxe těla funkce Pokud obsahuje více než jeden výraz, můžete pro tělo funkce šipky použít tradiční syntaxi funkce. To znamená, že funkci zabalte do složených závorek a přidejte klíčové slovo return:

Var sum = (num1, num2) => ( return num1 + num2; ) // ekvivalent k var sum = function(num1, num2) ( return num1 + num2; );
Tělo funkce bude zpracováno úplně stejně jako u klasických funkcí, až na to, že hodnoty speciální proměnné toto , super a argumenty budou hodnoceny odlišně.

Objektový literál Samostatně je třeba zmínit, že tělo funkce, která neobsahuje složené závorky a jednoduše vrací objektový literál, by mělo být uzavřeno v závorkách:

Var getTempItem = id => (( id: id, název: "Temp" )); // ekvivalentní k var getTempItem = function(id) ( return ( id: id, name: "Temp" ) );
Umístěním objektového literálu do závorek sdělujete analyzátoru, že složené závorky nejsou začátkem tradiční syntaxe těla funkce, ale začátkem literálu.

Proměnný počet parametrů Vzhledem k tomu, že objekt „nativní“ arguments není k dispozici uvnitř funkce šipky (hodnota argumentů je lexikálně vztažena k hodnotě argumentů tradiční funkce, ve které byla funkce šipky deklarována), pak pro funkce šipky s proměnný počet parametrů, ze kterých potřebujete použít zbývající vzor destrukční vzory. Příklad:

Var getTempItems = (...zbytek) => zbytek; // ekvivalentní k var getTempItems = function() ( return .slice.apply(arguments) );

Destrukční šablona jako parametr Pro účely tohoto článku neuvažujeme destrukční vzory – o nich si můžete přečíst v článku Přehled ECMAScript 6, další verze JavaScriptu, i když tyto informace jsou částečně zastaralé.

Jak můžete vidět z předchozího příkladu, i když má funkce šipky pouze jeden argument, musíte při použití destrukční vzory jako jediný parametr funkce. Příklady s ostatními šablony:

Var a = ((a)) => a; var b = ([b]) => b;

Použití funkcí šipek Nastavení kontextu Jedním z běžných scénářů v JavaScriptu je nastavení správné této hodnoty uvnitř funkce (vazba). Protože hodnotu tohoto lze změnit v závislosti na kontextu, ve kterém se funkce provádí, je možné omylem působit na jeden objekt, když jste mysleli něco úplně jiného. Podívejte se na následující příklad:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", function(event) ( this.doSomething(event.type); // error )); ), doSomething: function( type) ( console.log("Obsluha " + zadejte + " pro " + this.id) ) );
Ve výše uvedeném kódu by měl objekt pageHandler zpracovávat kliknutí na stránku. Metoda init() připojí k požadované události handler, který interně volá this.doSomething() . Kód však nebude fungovat správně. Odkaz na this.doSomething() není platný, protože ukazuje na objekt dokumentu uvnitř obslužné rutiny události namísto zamýšleného pageHandler . Pokud se pokusíte spustit tento kód, zobrazí se chyba, protože objekt dokumentu nemá metodu doSomething.

Hodnotu this můžete svázat s objektem pageHandler pomocí handleEvent nebo voláním standardní metody bind() ve funkci:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", (function(event) ( this.doSomething(event.type); // error )).bind(this)) ), doSomething: function(type) ( console.log("Obsluha " + typ + " for " + this.id) ) );
Nyní kód funguje tak, jak má, ale vypadá těžkopádněji. Navíc voláním bind(this) pokaždé, když vytvoříte novou funkci, jejíž hodnota je svázána s hodnotou pageHandler , ale kód funguje tak, jak jste zamýšleli.

Šipkové funkce řeší problém elegantnějším způsobem, protože pro hodnotu this (stejně jako super a argumenty) používají lexikální vazbu a její hodnota je určena hodnotou this v místě, kde byla funkce šipky vytvořena. Například:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", event => this.doSomething(event.type)); ) , doSomething: function(type) ( console.log( "Obsluha " + zadejte + " pro " + this.id) ));
V tomto příkladu je handlerem funkce šipky, která volá this.doSomething() . Hodnota tohoto bude stejná jako ve funkci init() a kód in v tomto příkladu bude fungovat správně, podobně jako ten, který používal bind() . Bez ohledu na to, zda volání this.doSomething() vrací hodnotu nebo ne, výraz uvnitř těla funkce šipky nemusí být uzavřen do složených závorek.

Výše uvedený příklad je navíc také efektivnější než volání bind(), protože je stejný jako následující kód pro prohlížeč:

Var pageHandler = ( id: "123456" , init: function() ( var self = this; document.addEventListener("click", function(event) ( return self.doSomething(event.type) )); ), doSomething: function(type) ( console.log("Obsluha " + typ + " for " + this.id) ) );
To znamená, že ke stvoření nedochází nová vlastnost, jako je tomu v případě volání bind().

„Vyhození“ kontextu mezi několik volání Je zřejmé, že můžete vnořit jednu funkci šipky do druhé, a tím přes ně „hodit“ hodnotu this:

Var obj = ( arr1: , arr2: ["a", "b", "c"] , concatenate: function(a, b)( return a + "|" + b ) , intersection: function() ( return this .arr1.reduce((sum, v1) => // funkce šipka 1 this.arr2.reduce((sum, v2) => ( // funkce šipka 2 sum.push(this.concatenate(v1, v2)) return součet ) , součet) , ) ); var arrSum = obj.intersection();//["1|a", "1|b", "1|c", "2|a", "2|b", "2|c", "3 |a", "3|b", "3|c"]

Použití jako argument Krátká syntaxe funkcí šipek z nich dělá ideální kandidáty pro předávání jako argumenty dalším voláním funkcí. Pokud například chcete seřadit pole, obvykle byste napsali něco takového:

Var vysledek = hodnoty.sort(funkce(a, b) ( return a - b ));
Docela podrobný pro jednoduchou obsluhu. Porovnejte s krátkým zápisem pro funkci šipky:

Var vysledek = hodnoty.sort((a, b) => a - b);
Použití metod, jako je array() , map() , reduction() a tak dále, lze zjednodušit pomocí syntaxe funkce krátké šipky.

Další vlastnosti funkcí šipek Přestože se funkce šipek liší od tradičních funkcí, mají některé společné rysy:
  • Operátor typeof vrátí "funkci" pro funkci šipky
  • Funkce šipky je také instancí třídy Function, takže instanceof bude fungovat stejně jako tradiční funkce
  • Stále můžete používat metody call() , apply() a bind(), ale nezapomeňte, že neovlivní hodnotu této metody.
  • Můžete použít metodu toMethod(), ta však nezmění hodnotu super ( metoda toMethod() byla představena v es6 a není zahrnuta v tomto článku).
Významný rozdíl od tradičních funkcí spočívá v tom, že pokus o volání funkce šipky pomocí operátoru new způsobí běhovou chybu. Shrnutí Funkce šipek jsou jednou z nejzajímavějších inovací v ECMAScriptu 6, která díky stručné definiční syntaxi zjednoduší práci. předávání funkcí jako hodnoty parametru jiné funkci.

Stručná syntaxe vám umožní psát složité věci ještě složitější a jednodušším způsobem. Například takto bude vypadat generátor identifikátorů (který na es5 vypadá mnohem podrobněji):

Nechť idGen = (start = 0, id = start, reset = (newId = start) => id = newId, next = () => id++) => ((reset, další)); nech gen = idGen(100); console.log(gen.next(), gen.next(), gen.reset(10), gen.next());//100 101 10 10
A lexikální vazba uzavře jeden z největších zdrojů bolesti a frustrace pro vývojáře a také zlepší výkon díky optimalizaci na úrovni js enginu.


Pokud si chcete vyzkoušet funkce šipek, můžete výše uvedené příklady spustit v konzole Firefoxu, která je zapnutá tento moment(02.2014 FF28) téměř plně podporuje funkce šipek (FF28 špatně počítá hodnotu argumentů ).

Můžete také vyzkoušet funkce šipek a další funkce es6 v ​​online překladači Traceur.

Štítky: Přidat štítky