Funkcie šípky Js. O kľúčovom slove JavaScript „toto“: funkcie použitia s vysvetleniami. Pravidlá používania funkcií šípok

Stali sa veľmi módnymi, vidíme ich vo všetkých nových článkoch. A ak na ne nie ste zvyknutí, len ťažko pochopíte moderný (ES6) kód obsahujúci funkcie šípok.

Účelom tohto článku nie je povedať vám, kedy alebo ako ich použiť. Pokúsim sa len vysvetliť novú syntax pre tých, ktorí ju vidia prvýkrát. Či ho používate alebo nie, nie je dôležité, no skôr či neskôr sa s tým predsa len niekde stretnete. Takže je lepšie pochopiť mechanizmus tejto novej syntaxe.

Tu je malý príklad:

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

Vyššie uvedený kód môže byť napísaný takto:

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

Alebo v v tomto prípade, ešte kratšie:

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

Druhý príklad používa ( ... ) zložené zátvorky, ale keďže ide len o jeden riadok kódu, zložené zátvorky možno vynechať a návrat je implikovaný, ako je vidieť v treťom príklade.

Jeden parameter

Ak má funkcia šípky jeden parameter, zátvorky možno vynechať:

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

Ak však neexistujú žiadne parametre, musíte použiť otváracie a zatváracie zátvorky:

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

Funkcie spätného volania

Šípky funkcií sú užitočné najmä pri spätných volaniach. Tí, ktorí poznajú JavaScript, poznajú jeho lexikálny rozsah, ktorý je celkom elegantný, ale dokáže robiť triky, ako je tento ( toto):

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

Existuje niekoľko variácií tohto „_toto“ (napríklad „ja“ alebo „tamto“), ale myšlienka je rovnaká. Vo funkciách spätného volania potrebujeme prístup k verzii vonkajšieho rozsahu, ale myšlienka je rovnaká. Vo funkciách spätného volania potrebujeme prístup k verzii tohto pre vonkajší rozsah, ktorá je teraz iná ako predtým, pretože hovoríme o funkcii spätného volania.

Používaním funkcie šípok, dostaneme „rozsah bloku“ a „toto“, čo je v oboch prípadoch rovnaké „toto“. To znamená, že vyššie uvedený kód možno prepísať bez _this = this:

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

"obal"

Predstavme si situáciu ako v Reacte, kde sa event po kliknutí by mal volať doSomething() , (), ale mal by tiež odovzdať argumenty doSomething() (napr. ID). Tento príklad v skutočnosti nefunguje:

Nejaký používateľ)))

Kód sa spustí, ale technicky okamžite po načítaní stránky zavolá doSomething(). Na vyriešenie tohto problému sa niektorí vývojári odvolávajú na funkciu wrapper:

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

Absencia zátvoriek v this.onClick znamená, že ide skôr o odkaz na funkciu ako o volanie funkcie.

Funkcia onClick() je teraz niečo ako obal pre doSomething() . Pomocou funkcií šípok môžete vytvoriť „obaly“ tohto typu:

Const User = React.createClass(function() ( render: function() ( return doSomething(this.props.userId))>Niektorý používateľ ) ))

Ako alternatívu by sme mohli použiť aj .bind() , ktorý nevyžaduje žiadne obaly (funkcie šípok alebo čokoľvek):

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

Podpora prehliadača pre funkcie šípok

Ak potrebujete podporu prehliadača inú ako najnovšie verzie Chrome A Firefox, použite Babel transpiler na konverziu kódu ES6, ktorý ste napísali, na ES5.

ES6 má nový spôsob vytvárania funkcií – pomocou operátora Arrow =>. Takéto funkcie sa nazývajú šípkové funkcie. Ponúkajú kompaktnejšiu syntax. Nemajú meno a s týmto pracujú inak .

Prvá vec, ktorú urobíme, je spustiť skript Babel, ktorý bude monitorovať súbory a vytvárať nové verzie, keď sa zmenia.

Otvorte priečinok projektu v príkazový riadok(KS). Zadajte príkaz:

A stlačte Enter

V priečinku src vytvoríme súbor arr.js a hneď ho označíme v súbore index.html

</script>

Najnovšie verzie prehliadačov podporujú funkcie šípok bez transpilácie a môj prehliadač je jednou z nich.

Napíšme funkciu, ktorá sčíta dve čísla a vráti ich súčet. Zavolajme funkciu add .

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

V konzole uvidíme výsledok - 9

Teraz preveďme túto funkciu na funkciu šípky.

Odstránime slovo funkcia , odstránime názov funkcie a zložené zátvorky a slovo - return . Za parametrami dáme šípku.

Nech sčítame = (x, y) => x + y; console.log(add(4, 6));

Ak sa pozriete na typ premennej add pomocou operátora typeof:

Console.log(typeof(add));

To je to, čo uvidíme vo funkčnej konzole

To znamená, že funkcie šípok sú bežné funkcie. A môžete si to overiť pohľadom na preložený kód.

"používať prísne"; var _typeof = typeof Symbol === "funkcia" && 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 = funkcia add(x, y) ( return x + y; ); console.log(add(4, 6)); console.log(typeof add === "undefined" ? "undefined" : _typeof(add));

Vidíme, že Babel zmenil náš kód na jednoduchý funkčný výraz.

Napíšme si jednoduchú funkciu, ktorá odmocní dané číslo.

Nech sčítame = (x, y) => x + y; console.log(add(4, 6)); console.log(typeof(add)); nech štvorec = funkcia(a) ( vráti a * a; ) console.log(square (4));

Pozrime sa do konzoly:

Funkcia šípky bude vyzerať takto:

Nech štvorec = x => x * x;

Ak má funkcia šípky iba jeden parameter, nie je potrebné ho uzatvárať do zátvoriek!

Napíšme funkciu, ktorá nemá žiadne parametre.

Funkcia givNumer () ( návrat 33; ) console.log(givNumer ());

Táto funkcia jednoducho vytlačí na konzolu číslo 33. Šípka:

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

Vytvorme funkciu, ktorá nebude nič vracať. Jednoducho zobrazí správu v konzole prehliadača.

Nech log = funkcia () ( console.log("Ahoj Svet!"); ); log();

Prepínač:

Nech log = () => console.log("Ahoj Svet!!!"); log();

Vytvorme funkciu, ktorej telo bude pozostávať z dvoch čiar.

Funkcia bude mať dva parametre. Vytvorme premennú v tele funkcie. Potom vrátime výsledok.

Nech mult = funkcia (a, b) ( nech vysledok = a * b; vrat vysledok; ) console.log(mult (4, 5));

Ak je vo funkcii šípky niekoľko riadkov, potom sú potrebné zložené zátvorky - ()! A nezabudnite definovať, čo táto funkcia vracia, pomocou kľúčového slova return

Prepínač:

Nech mult = (a, b) => ( nech výsledok = a * b; vráti výsledok; ) console.log(mult (4, 5));

Teraz vytvorte funkciu, ktorá vráti objektový literál:

Nech literal = function () ( return ( name: "John"); ) console.log (literal ());

V konzole uvidíme:

Teraz sa pokúsime vytvoriť funkciu šípky, ktorá vráti objektový literál.

Malo by sa pamätať na to, že ak funkcia šípky vráti objektový literál, potom sú potrebné zátvorky - ()

Funkcia šípky, ktorá vracia objektový literál:

Nech doslovné = () => ((meno: "Ján")); console.log(literal());

Teraz skúsme použiť funkciu šípky ako IIFE – výraz okamžite vyvolanej funkcie

V skratke ide o funkciu, ktorá sa vykoná ihneď po vyhlásení

Vyzerá to takto:

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

Funkcia šípky IIFE bude vyzerať takto:

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

Dôležitou vlastnosťou funkcií šípok je, že šípka musí prísť hneď po parametroch!

Nemôžete to len tak vziať a presunúť o riadok nižšie. Vypíše chybu!

Praktická aplikácia funkcií šípok. Funkcie šípok sú veľmi pohodlné na použitie s poľami.

Vytvorme pole s niekoľkými číslami a nazvime ho čísla . Myslím, že viete, že polia majú užitočné metódy, ktoré vám umožňujú iterovať pole, filtrovať ho atď.

Vypočítajme súčet všetkých premenných poľa. Aby som to urobil, deklarujem ďalšiu premennú - nech súčet = 0;

Použime metódu forEach(), ktorú má každé pole, budeme iterovať prvky a pridávať k súčtu.

Nech čísla = ; nech súčet = 0; cisla.pre kazdeho(funkcia(num) (sucet += cislo; )); console.log(sum);

V konzole uvidíme 55. Premeňme túto funkciu na funkciu šípok: cisla.forEach(num => suma += num); console.log(sum);

Takže to, čo nám predtým trvalo tri riadky, teraz trvá jeden.

Môžeme tiež odmocniť každý prvok poľa.

Nech na druhú = čísla.map(n => n * n); console.log(štvorec);

Funkcie šípok a toto. Na to si vytvorím objektový literál, ktorý uložím do premennej osoba.

Objekt osoba bude mať vlastnosť name s hodnotou 'Bob' a vlastnosť pozdravu s hodnotou 'Greet'. Pozdrav vytlačíme do konzoly a tiež sa pozrieme na účel tohto .

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( console.log("Ahoj! Moje meno je " + toto.meno); console.log(toto; ) ); osoba.pozdrav();

V konzole prehliadača uvidíme pozdrav a samotný objekt osoby.

Teraz nahradíme funkciu šípkou a uvidíme, čo sa s tým stane.

Nech osoba = ( meno: "Bob", pozdrav: () => ( console.log("Ahoj! Moje meno je " + toto.meno); console.log(toto; ) ); osoba.pozdrav();

Teraz sme nedostali hodnotu názvu a hodnota tohto je okno!

Ale prečo? Ide o to, že hodnota tohto je prevzatá z kontextu, v ktorom je funkcia deklarovaná. ! Bez ohľadu na to, kde bude táto funkcia vykonaná. Toto je možné vidieť na obrázku:

Máme program.

Zatiaľ v ňom okrem okenného objektu nič nie je. Pridaný objekt osoby. Všimnite si, že pre metódu používame funkciu šípky. Ako sme povedali, hodnota tohto sa bude brať z kontextu. Kontext je prostredie. V tomto prípade bude prostredie objektu osoby, všetky jeho vlastnosti a metódy okenný objekt. A ak je hodnota tohto prevzatá z kontextu, potom to bude odkazovať na objekt okna.

Ak sa pozrieme na pravidelnú funkciu, potom vieme, že sa to týka samotného objektu osoby. Môžete sa opýtať, prečo je hodnota tohto vo funkciách šípok prevzatá z kontextu? A odpoveď je veľmi jednoduchá – urobili to tak! :-) Ide o to, že funkcie šípok vznikli na riešenie problémov v inej situácii. Pozrime sa na príklad. Aby sme videli problém, vrátime sa k našej funkcii šípky.

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( console.log("Ahoj! Moje meno je " + toto.meno); console.log(toto; ) );

Predstavme si, že náš Bob je dosť zaneprázdnený a potrebuje pár sekúnd na dokončenie svojej práce. Počkajte 2 sekundy. simulujeme pomocou funkcie setTimeout(); .Táto funkcia berie funkciu ako prvý parameter a počet milisekúnd na čakanie ako druhý parameter.

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( setTimeout(funkcia () ( console.log("Ahoj! Volám sa " + toto.meno); console.log(to); ), 2000) ;) ); osoba.pozdrav();

Ak máte skúsenosti s JavaScriptom, myslím, že chápete, v čom je problém. Každopádne, pozrime sa, čo sa stane v prehliadači. Presne o dve sekundy neskôr uvidíme tento obrázok v prehliadači.

Ale prečo? Ak sa pozriete na náš kód, je logické predpokladať. že to odkazuje na objekt osoby, pretože používame bežnú funkciu. Ide o to, že setTimeout() patrí objektu okna. Ak to napíšete takto: window.setTimeout() , čo si myslíte, že to znamená? A v konzole dostaneme rovnaký výsledok! Existuje niekoľko spôsobov, ako vyriešiť tento problém v ES5. Pozrime sa na tú najbežnejšiu: Pred setTimeout() deklarujem inú premennú a priradím túto ako hodnotu. A teraz v tele funkcie namiesto tohto označíme toto.

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( nech to = toto; setTimeout(funkcia () ( console.log("Ahoj! Moje meno je " + tamto.meno); console.log(to) ;)), 2000);)); osoba.pozdrav();

Teraz, vďaka uzáveru, bude mať funkcia, ktorú pošleme do setTimeout(), prístup k premennej that, ktorej hodnota bude this , teda v tomto prípade objekt osoba.

Pre prehľadnosť sa môžete pozrieť na to, na čo sa to a toto vzťahuje.

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( nech to = toto; setTimeout(funkcia () ( console.log("Ahoj! Moje meno je " + tamto.meno); console.log("It is my That = " + that); console.log("It is my This = " + this); ), 2000); ) ); osoba.pozdrav();

V konzole uvidíme potvrdenie:

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

V ES6 môžeme na vyriešenie tohto problému jednoducho použiť funkciu šípky.

Nech osoba = ( meno: "Bob", pozdrav: funkcia () ( setTimeout(() => ( console.log("Ahoj! Moje meno je " + toto.meno); console.log("To je moje toto = " + toto); ), 2000); )); osoba.pozdrav();

V dôsledku toho uvidíme v konzole:

IN grafický príklad pre funkciu šípky bude kontextom objekt osoby, nie objekt okna. preto sa to bude týkať osoby.

Okrem kompaktnej syntaxe boli zavedené funkcie šípok na riešenie problémov, ako sú tieto.

Pre referenciu môžete vidieť, ako to Babel vyriešil

Var osoba = ( meno: "Bob", pozdrav: funkcia pozdrav() ( var _this = toto; setTimeout(funkcia () ( console.log("Ahoj! Moje meno je " + _this.name); console.log(" Je to moje Toto = " + _toto); ), 2000); )); osoba.pozdrav(); Babel použil rovnakú metódu, akú sme použili v ES5. Jediný rozdiel je v tom, že premennú sme nazvali that a Babel ju nazval - _this. Vďaka uzavretiu bude mať funkcia, ktorú pošleme do setTimeout, prístup k premennej _this a v dôsledku toho k objektu osoba.

Myslím, že najťažšou časťou tejto časti je pochopiť, ako fungujú uzávery.

Niektoré ďalšie funkcie funkcií šípok:
Viac informácií o ES6 a funkciách šípok nájdete v mojom príspevku

Ahojte všetci! V tomto článku sa pozrieme na to, aké funkcie šípok sú v ES6 a ako ich používať.

Funkcie šípok sú funkcie, ktoré sa zapisujú pomocou operátora šípky (=>).

Pozrime sa hneď na príklad:

Nech sčítame = (x, y) => x + y;
console.log(add(5, 2));

V dôsledku vykonania tejto funkcie uvidíme v konzole číslo 7.

Najprv odovzdáme argumenty v zátvorkách, potom vložíme znak šípky a potom napíšeme kód samotnej funkcie. V našom prípade jednoducho vezme dve čísla a pridá ich. Teoreticky je to rovnaké ako vyjadrenie funkcie v ES5. Ak používate Babel alebo podobné kompilátory, s najväčšou pravdepodobnosťou napíšu niečo takéto:

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

Ak vaša funkcia berie len jeden parameter, zátvorky sú voliteľné.

Nech štvorec = x => x*x;

Táto funkcia berie iba jeden argument a odmocňuje dané číslo.

Funkcia bez parametrov:

Nech func = () => 77;

Ak vaša funkcia obsahuje niekoľko riadkov, tak v prvom rade musíte použiť zložené zátvorky a v druhom rade nezabudnite napísať, čo funkcia vracia, t.j. použite kľúčové slovo return.

Vynásobme = (x, y) => (
nech vysledok = x*y;
vrátiť výsledok;
};

Ak potrebujete vrátiť doslovný objekt, musíte ho zabaliť do zátvoriek:

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

Funkcia samovyvolania vyzerá takto:

Výraz funkcie šípky je syntakticky kompaktnou alternatívou k výrazu regulárnej funkcie, aj keď bez vlastných väzieb na kľúčové slová this , arguments , super alebo new.target. Výrazy funkcie šípok nie sú vhodné ako metódy a nemožno ich použiť ako konštruktory.

Syntax Základná syntax (param1, param2, …, paramN) => ( príkazy ) (param1, param2, …, paramN) => výraz // ekvivalent: => ( návratový výraz; ) // Zátvorky sú voliteľné, ak je iba jeden názov parametra: (singleParam) => ( príkazy ) singleParam => ( príkazy ) // Zoznam parametrov pre funkciu bez parametrov by mal byť napísaný s párom zátvoriek. () => ( príkazy ) Pokročilá syntax // Uveďte do zátvoriek telo funkcie, aby sa vrátil doslovný výraz objektu: params => ((foo: bar)) // Ostatné parametre a predvolené parametre sú podporované (param1, param2, ...rest) => ( príkazy ) (param1 = defaultValue1, param2, …, paramN = defaultValueN) => ( príkazy ) // Deštrukturalizácia v rámci zoznamu parametrov je tiež podporovaná var f = ( = , (x: c) = (x: a + b)) => a + b + c; f(); // 6 Popis

Zavedenie funkcií šípok ovplyvnili dva faktory: potreba kratších funkcií a správanie kľúčového slova this.

Kratšie funkcie var prvky = [ "Vodík", "Hélium", "Lítium", "Beryllium" ]; // Tento príkaz vráti pole: elements.map (function(element) ( return element.length; )); // Normálnu funkciu vyššie možno zapísať ako funkciu šípky pod elements.map((element) => ( return element.length; )); // // Keď je tam len jeden parameter, môžeme odstrániť okolité zátvorky elements.map (element => ( return element.length; )); // // Keď je jediným príkazom vo funkcii šípky `return`, môžeme odstrániť `return` a odstrániť // okolité zložené zátvorky elements.map(element => element.length); // // V tomto prípade, pretože potrebujeme iba vlastnosť length, môžeme použiť parameter deštrukturovania: // Všimnite si, že `length` zodpovedá vlastnosti, ktorú chceme získať, zatiaľ čo // zjavne nešpeciálna `lengthFooBArX` je len názov premennej, ktorý je možné zmeniť // na ľubovoľný platný názov premennej, ktorý chcete elements.map ((( length:lengthFooBArX )) => lengthFooBArX); // // Toto priradenie deštruktívneho parametra možno zapísať aj tak, ako je uvedené nižšie. Všimnite si však, že v // tomto príklade nepriraďujeme hodnotu `length` k vytvorenej vlastnosti. Namiesto toho sa ako vlastnosť, ktorú chceme z objektu získať, použije doslovný názov // samotný premennej `length`. prvky.mapa ((( dlzka )) => dlzka); // Toto nie je oddelené

Pred funkciami šípok každá nová funkcia definovala svoju vlastnú túto hodnotu na základe toho, ako bola funkcia volaná:

  • Nový objekt v prípade konštruktora.
  • nedefinované vo volaniach funkcií v prísnom režime.
  • Základný objekt, ak bola funkcia volaná ako "metóda objektu".

Ukázalo sa, že pri objektovo orientovanom štýle programovania to nie je ideálne.

Funkcia Person() ( // Konštruktor Person() definuje `this` ako svoju inštanciu. this.age = 0; setInterval(function growUp() ( // V neprísnom režime funkcia growUp() definuje ` this` // ako globálny objekt (pretože je to miesto, kde sa vykonáva growUp().), // ktorý sa líši od `this` // definovaného konštruktorom Person(). this.age++; ), 1000) ;) var p = nová osoba();

V ECMAScript 3/5 sa tento problém dal vyriešiť priradením hodnoty v tomto premennej, ktorú možno uzavrieť.

Funkcia Osoba() ( var that = this; that.age = 0; setInterval(function growUp() () ( // Spätné volanie odkazuje na premennú `that`, ktorej // hodnota je očakávaný objekt. that.age++; ) , 1000); ) "použiť prísne"; var obj = (a: 10); Object.defineProperty(obj, "b", ( get: () => ( console.log(this.a, typeof this.a, this); // undefined "undefined" Window (...) (alebo globálne object) return this.a + 10; // predstavuje globálny objekt "Window", preto "this.a" vráti "undefined" ) ));

Použitie nového operátora

Funkcie šípok nemožno použiť ako konštruktory a pri použití s ​​novým súborom generujú chybu.

Var Foo = () => (); var foo = new Foo(); // TypeError: Foo nie je konštruktor

Použitie vlastnosti prototypu

Funkcie šípok nemajú vlastnosť prototypu.

Var Foo = () => (); console.log(Foo.prototype); // nedefinované

Použitie kľúčového slova výnos

Kľúčové slovo výnos sa nesmie použiť v tele funkcie šípky (okrem prípadov, keď je to povolené v rámci funkcií, ktoré sú v nej ďalej vnorené). V dôsledku toho sa funkcie šípok nedajú použiť ako generátory.

Funkčné telo

Funkcie šípok môžu mať buď „stručné telo“ alebo obvyklé „blokové telo“.

V stručnom tele je špecifikovaný iba výraz, ktorý sa stáva implicitnou návratovou hodnotou. V tele bloku musíte použiť explicitný príkaz return.

Var func = x => x * x; // stručná syntax tela, implikovaný "return" var func = (x, y) => ( return x + y; ); // s telom bloku, je potrebný explicitný "návrat".

Vracanie objektových literálov

Majte na pamäti, že vrátenie objektových literálov pomocou parametrov stručnej syntaxe tela => (object:literal) nebude fungovať podľa očakávania.

Var func = () => ( foo: 1 ); // Volanie funkcie func() vráti hodnotu undefined! var func = () => ( foo: function() () ); // SyntaxError: príkaz funkcie vyžaduje názov

Je to preto, že kód v zložených zátvorkách (()) je analyzovaný ako postupnosť príkazov (t. j. s foo sa zaobchádza ako s označením, nie ako kľúčom v objektovom literáli).

Objekt musíte zabaliť do zátvoriek:

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

Zalomenie riadkov

Funkcia šípky nemôže obsahovať zalomenie riadku medzi jej parametrami a šípkou.

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

Dá sa to však zmeniť vložením zalomenia riadka za šípku alebo použitím zátvoriek/zátvoriek, ako je uvedené nižšie, aby sa zabezpečilo, že kód zostane pekný a nadýchaný. Medzi argumenty môžete vložiť aj zlomy riadkov.

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; // nebola vyvolaná chyba SyntaxError

Poradie analýzy

Aj keď šípka vo funkcii šípky nie je operátor, funkcie šípky majú špeciálne pravidlá analýzy, ktoré v porovnaní s bežnými funkciami interagujú s prioritou operátora odlišne.

Nechajte spätné volanie; spätné volanie = spätné volanie || funkcia(); // ok spätné volanie = spätné volanie || () => (); // SyntaxError: neplatné argumenty funkcie šípky callback = callback || (() => ()); // dobre

Ďalšie príklady // Funkcia prázdnej šípky vracia nedefinované nech prázdne = () => (); (() => "foobar")(); // Vráti "foobar" // (toto je výraz okamžite vyvolanej funkcie) var simple = a => a > 15 ? 15: a; jednoduchý(16); // 15 jednoduchých(10); // 10 nech max = (a, b) => a > b ? a: b; // Jednoduché filtrovanie polí, mapovanie, ... var arr = ; var sum = arr.reduce((a, b) => a + b); // 66 var párne = arr.filter(v => v % 2 == 0); // var double = arr.map(v => v * 2); // // Výstižnejšie reťazce sľubov sľub.then(a => ( // ... )).then(b => ( // ... )); // Funkcie šípok bez parametrov, ktoré sa vizuálne ľahšie analyzujú setTimeout(() => ( console.log("Urobím to skôr"); setTimeout(() => ( // hlbší kód console.log("Urobím to neskôr") ;)), jedenásť); technické údaje Poznámka k stavu špecifikácie
ECMAScript 2015 (6. vydanie, ECMA-262)
Štandardné Počiatočná definícia.
Najnovší koncept ECMAScript (ECMA-262)
Definícia "definície šípkových funkcií" v tejto špecifikácii.
Návrh
Kompatibilita prehliadača

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

Aktualizujte údaje o kompatibilite na GitHub

Desktop Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Webové zobrazenie Android Chrome pre Android Firefox pre Android Opera pre Android Safari na iOS Samsung Internet Node.jsFunkcie šípok Koncová čiarka v parametroch
Plná podpora prehliadača Chrome 45Plná podpora Edge ÁnoPlná podpora Firefoxu 22

Poznámky

Plná podpora 22

Poznámky

Poznámky Pred Firefoxom 39 bol za argumentmi funkcie šípky nesprávne povolený znak ukončenia riadku (\n). Toto bolo opravené, aby vyhovovalo špecifikácii ES2015 a kódu ako () \n =>
IE Žiadna podpora NieOpera plná podpora 32Plná podpora Safari 10WebView Plná podpora pre Android 45Chrome Plná podpora pre Android 45Firefox Plná podpora pre Android 22

Poznámky

Plná podpora 22

Poznámky

Poznámky Počiatočná implementácia funkcií šípok vo Firefoxe ich automaticky sprísnila. Toto bolo zmenené od verzie Firefox 24. Použitie „use strict“; sa teraz vyžaduje. Poznámky Pred Firefoxom 39 bol za argumentmi funkcie šípky nesprávne povolený znak ukončenia riadku (\n). Toto bolo opravené, aby vyhovovalo špecifikácii ES2015 a kód ako () \n => () teraz v tejto a novších verziách vyvolá chybu SyntaxError.
Opera Android Plná podpora 32Safari iOS Plná podpora 10Samsung Internet Android Plná podpora 5.0nodejs Plná podpora Áno
Plná podpora prehliadača Chrome 58Hrana?Plná podpora Firefoxu 52IE Žiadna podpora NieOpera plná podpora 45Safari?WebView Plná podpora pre Android 58Chrome Plná podpora pre Android 58Firefox Plná podpora pre Android 52Opera Android Plná podpora 43Safari iOS?Samsung Internet Android Plná podpora 7.0nodejs Plná podpora Áno
Legenda Úplná podpora Úplná podpora Žiadna podpora Žiadna podpora Kompatibilita neznáma Kompatibilita neznáma Pozrite si poznámky k implementácii. Pozri implementačné poznámky.
  • Návod

Jednou z najzaujímavejších častí nového štandardu ECMAScript 6 sú funkcie šípok. Funkcie šípok, ako už názov napovedá, sú definované novou syntaxou, ktorá používa šípku => . Okrem vynikajúcej syntaxe sa však funkcie šípok od tradičných funkcií líšia aj inými spôsobmi:

  • Lexikálna väzba. hodnoty špeciálne premenné argumenty this , super a nie sú určené tým, ako boli funkcie šípok volané, ale tým, ako boli vytvorené.
  • Nemenné toto , super a argumenty . Hodnoty týchto premenných vo funkciách šípok zostávajú nezmenené životný cyklus funkcie.
  • Funkcie šípok nemožno použiť ako konštruktor a pri použití s ​​operátorom new vyvolávajú chybu.
  • Nedostupnosť „natívnej“ hodnoty premennej argumenty.
Dôvodov na zavedenie týchto rozdielov bolo niekoľko. Prvým je, že väzba sa v JavaScripte používa pomerne často. Pri používaní tradičných funkcií je veľmi ľahké stratiť správnu túto hodnotu, čo môže viesť k neočakávaným následkom. Ďalším dôvodom je, že motory JS budú môcť vďaka týmto obmedzeniam jednoducho optimalizovať vykonávanie funkcií šípok (na rozdiel od tradičných funkcií, ktoré možno použiť ako konštruktor a môžu sa voľne upravovať špeciálne premenné).


Poznámka: Tento článok je kompiláciou z voľného prekladu článku Pochopenie funkcií šípok ECMAScript 6 a čítania najnovšieho návrhu špecifikácie (20. januára 2014, návrh Rev 22).

Syntax Vo všeobecnosti syntax funkcií šípok vyzerá takto:

Var fun = (x) => x;
Je veľmi podobná podobnej syntaxi v jazykoch ako Scala, CoffeeScript a syntaxi lambda výrazov z C#.

Syntax funkcií šípok sa môže líšiť v závislosti od toho, ako funkciu deklarujete. Deklarácia vždy začína zoznamom argumentov, za ktorými nasleduje šípka a telo funkcie. Zoznam argumentov aj telo funkcie môžu mať rôzne formy v závislosti od toho, čo píšete.

Jeden parameter Deklarovanie funkcie šípky, ktorá vezme jeden argument a jednoducho ho vráti, je veľmi jednoduché:

Var reflect = hodnota => hodnota; // ekvivalent k var reflect = function(value) (return value; )
Keď má funkcia šípky iba jeden argument, možno ju deklarovať bez zátvoriek. Telo funkcie za šípkou tiež nemusí mať žiadne zložené zátvorky a nemusí obsahovať kľúčové slovo return.

Viaceré parametre Ak však chcete deklarovať viac ako jeden parameter, musíte zoznam parametrov uzavrieť do zátvoriek:

Var sum = (num1, num2) => num1 + num2; // ekvivalent k var sum = function(num1, num2) ( return num1 + num2; );
Funkcia súčtu jednoducho pridá dva argumenty. Jediný rozdiel oproti predchádzajúcemu príkladu je prítomnosť zátvoriek a čiarky (rovnako ako v tradičných funkciách).

Žiadne parametre Podobne funkcia bez akýchkoľvek argumentov musí mať prázdny zoznam parametrov uzavretý v zátvorkách:

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

Tradičná syntax tela funkcie Pre telo funkcie šípky môžete použiť tradičnú syntax funkcie, ak obsahuje viac ako jeden výraz. To znamená, že zabaľte funkciu do zložených zátvoriek a pridajte kľúčové slovo return:

Var sum = (num1, num2) => ( return num1 + num2; ) // ekvivalent k var sum = function(num1, num2) ( return num1 + num2; );
Telo funkcie bude spracované úplne rovnako ako pri klasických funkciách, až na to, že hodnoty špeciálne premenné toto , super a argumenty budú hodnotené inak.

Objektový literál Samostatne by sa malo spomenúť, že telo funkcie, ktorá neobsahuje zložené zátvorky a jednoducho vracia objektový literál, by malo byť uzavreté v zátvorkách:

Var getTempItem = id => (( id: id, názov: "Temp" )); // ekvivalent k var getTempItem = function(id) ( return ( id: id, name: "Temp" ) );
Umiestnenie literálu objektu do zátvoriek hovorí syntaktickému analyzátoru, že zložené zátvorky nie sú začiatkom tradičnej syntaxe tela funkcie, ale začiatkom literálu.

Premenlivý počet parametrov Keďže objekt „native“ arguments nie je dostupný vo vnútri funkcie šípky (hodnota argumentov je lexikálne príbuzná hodnote argumentov tradičnej funkcie, v rámci ktorej bola funkcia šípky deklarovaná), potom pre funkcie šípok s variabilný počet parametrov, z ktorých musíte použiť zvyšok vzoru deštruktívne vzory. Príklad:

Var getTempItems = (...rest) => rest; // ekvivalent k var getTempItems = function() ( return .slice.apply(arguments) );

Šablóna deštrukcie ako parameter Na účely tohto článku neuvažujeme o deštruktívnych vzoroch - môžete si o nich prečítať v článku Prehľad ECMAScript 6, ďalšej verzie JavaScriptu, aj keď sú tieto informácie čiastočne zastarané.

Ako môžete vidieť z predchádzajúceho príkladu, aj keď má funkcia šípky iba jeden argument, stále musíte pri použití deštruktívne vzory ako jediný parameter funkcie. Príklady s ostatnými šablóny:

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

Používanie funkcií šípok Nastavenie kontextu Jedným bežným scenárom v JavaScripte je nastavenie správnej tejto hodnoty vo funkcii (väzba). Pretože hodnotu tohto možno zmeniť v závislosti od kontextu, v ktorom sa funkcia vykonáva, je možné omylom pôsobiť na jeden objekt, keď ste mysleli niečo úplne iné. Pozrite si nasledujúci príklad:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", function(event) ( this.doSomething(event.type); // error )); ), doSomething: function( typ) ( console.log("Obsluha " + typ + " pre " + toto.id) ) );
Vo vyššie uvedenom kóde by mal objekt pageHandler spracovávať kliknutia na stránku. Metóda init() pripojí k požadovanej udalosti handler, ktorý interne volá this.doSomething() . Kód však nebude fungovať správne. Odkaz na this.doSomething() nie je platný, pretože ukazuje na objekt dokumentu vo vnútri obsluhy udalosti namiesto zamýšľaného pageHandler . Ak sa pokúsite spustiť tento kód, zobrazí sa chyba, pretože objekt dokumentu nemá metódu doSomething.

Hodnotu this môžete naviazať na objekt pageHandler pomocou handleEvent alebo volaním štandardnej metódy bind() vo funkcii:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", (function(event) ( this.doSomething(event.type); // error )).bind(this)) ; ) , doSomething: function(type) ( console.log("Spracovanie " + napíšte + " pre " + toto.id) ) );
Teraz kód funguje tak, ako má, ale vyzerá ťažkopádnejšie. Okrem toho volaním bind(this) zakaždým, keď vytvoríte novú funkciu, ktorej hodnota je prepojená s hodnotou pageHandler , ale kód funguje tak, ako ste zamýšľali.

Funkcie šípok riešia problém elegantnejším spôsobom, pretože pre hodnotu this (ako aj super a argumenty) používajú lexikálnu väzbu a jej hodnota je určená hodnotou this v mieste, kde bola funkcia šípky vytvorená. Napríklad:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", event => this.doSomething(event.type)); ) , doSomething: function(type) ( console.log( "Obsluha " + zadajte + " pre " + this.id) ) );
V tomto príklade je handlerom funkcia šípky, ktorá volá this.doSomething() . Hodnota tohto bude rovnaká ako vo funkcii init() a kód in v tomto príklade bude fungovať správne, podobne ako ten, ktorý používal bind() . Bez ohľadu na to, či volanie this.doSomething() vráti hodnotu alebo nie, výraz v tele funkcie šípky nemusí byť uzavretý do zložených zátvoriek.

Okrem toho je vyššie uvedený príklad tiež efektívnejší ako volanie bind(), pretože je rovnaký ako nasledujúci kód pre prehliadač:

Var pageHandler = ( id: "123456" , init: function() ( var self = toto; document.addEventListener("click", function(event) ( return self.doSomething(event.type) )); ), doSomething: function(type) ( console.log("Obsluha " + typ + " for " + this.id) ) );
To znamená, že k stvoreniu nedochádza Nová funkcia, ako je to v prípade volania bind().

„Vhadzovanie“ kontextu medzi niekoľkými hovormi Je zrejmé, že jednu funkciu šípky môžete vložiť do druhej, čím cez ne „prehodíte“ túto hodnotu:

Var obj = ( arr1: , arr2: ["a", "b", "c"] , zreťaziť: function(a, b)( return a + "|" + b ) , intersection: function() ( return this .arr1.reduce((sum, v1) => // funkcia šípky 1 this.arr2.reduce((sum, v2) => ( // funkcia šípky 2 sum.push(this.concatenate(v1, v2)) return súčet; ) , súčet) , ) )); var arrSum = obj.intersection();//["1|a", "1|b", "1|c", "2|a", "2|b", "2|c", "3 |a", "3|b", "3|c"]

Použitie ako argument Krátka syntax funkcií šípok z nich robí ideálnych kandidátov na odovzdanie ako argumenty iným volaniam funkcií. Napríklad, ak chcete triediť pole, zvyčajne by ste napísali niečo takéto:

Var vysledok = hodnoty.sort(funkcia(a, b) ( return a - b ));
Docela podrobný pre jednoduchú obsluhu. Porovnajte s krátkym zápisom funkcie šípky:

Var vysledok = hodnoty.sort((a, b) => a - b);
Použitie metód ako array() , map() , reduction() atď. možno zjednodušiť pomocou syntaxe funkcie krátkej šípky.

Ďalšie funkcie funkcií šípok Aj keď sa funkcie šípok líšia od tradičných funkcií, majú niektoré spoločné vlastnosti:
  • Operátor typeof vráti "funkciu" pre funkciu šípky
  • Funkcia šípky je tiež inštanciou triedy Function, takže instanceof bude fungovať rovnako ako s tradičnou funkciou
  • Stále môžete použiť metódy call() , apply() a bind(), ale nezabudnite, že neovplyvnia hodnotu tohto
  • Môžete použiť metódu toMethod(), nezmení však hodnotu super ( Metóda toMethod() bola zavedená v es6 a tento článok ju nepokrýva).
Významný rozdiel oproti tradičným funkciám spočíva v tom, že pokus o zavolanie funkcie šípky pomocou operátora new spôsobí chybu pri behu Zhrnutie Funkcie šípok sú jednou z najzaujímavejších inovácií v ECMAScript 6, ktorá vďaka stručnej syntaxi definícií zjednoduší odovzdávanie funkcií ako hodnoty parametra inej funkcii.

Stručná syntax vám umožní písať zložité veci ešte zložitejšie a jednoduchším spôsobom. Napríklad takto bude vyzerať generátor identifikátorov (ktorý na es5 vyzerá oveľa podrobnejšie):

Nech idGen = (start = 0, id = štart, reset = (newId = start) => id = newId, next = () => id++) => ((reset, next)); nech gen = idGen(100); console.log(gen.next(), gen.next(), gen.reset(10), gen.next());//100 101 10 10
A lexikálna väzba uzavrie jeden z najväčších zdrojov bolesti a frustrácie pre vývojárov a tiež zlepší výkon vďaka optimalizácii na úrovni js enginu.


Ak si chcete vyskúšať funkcie šípok, vyššie uvedené príklady môžete spustiť v konzole Firefoxu, ktorá je zapnutá tento moment(02.2014 FF28) takmer plne podporuje funkcie šípok (FF28 nesprávne vypočítava hodnotu argumentov).

Môžete tiež vyskúšať funkcie šípok a ďalšie funkcie es6 v ​​online prekladači Traceur.

Štítky: Pridajte štítky