Bezpečnosť.  Nastaviť.  Internet.  zotavenie.  Inštalácia

ES6. Funkcie šípok v javascripte

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:

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.

Otvorme priečinok projektu v príkazovom riadku (CS). 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 person, všetky jeho vlastnosti a metódy objektom okna. 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:

V grafickom príklade by kontext pre funkciu šípky bol 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

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.
  • Preklad

Funkcie tučných šípok (=>), známe aj ako funkcie šípok, sú úplne novou funkcionalitou v ECMAScript 2015 (predtým známy ako ES6). Ak sa má veriť fámam, tak v ECMAScripte 2015 sa pod vplyvom CoffeeScriptu začala namiesto –> syntax používať => syntax. Tiež podobnosť kontextu prenáša toto.

Funkcie šípok majú dva hlavné účely: poskytnúť stručnejšiu syntax; zabezpečiť, aby sa lexikálne toto odovzdalo s nadradeným rozsahom. Poďme sa na každú z nich pozrieť bližšie!

Syntax novej funkcie Klasická syntax funkcie JavaScriptu je nepružná, či už ide o funkciu s jednou premennou alebo o stránku s mnohými funkciami. Zakaždým, keď deklarujete funkciu, musíte napísať function()(). Potreba stručnejšej syntaxe funkcií bola jedným z dôvodov, prečo sa CoffeeScript stal veľmi populárnym. Táto potreba je zrejmá najmä v prípade malých funkcií spätného volania. Poďme sa pozrieť na reťazec Promise:
function getVerifiedToken(selector) ( return getUsers(selector) .then(function (users) ( return users; )).then(verifyUser) .then(function (používateľ, overenýToken) ( return ověřenýToken; )) .catch(function (err) ) ( log(err.stack); )); )
Vyššie môžete vidieť viac či menej stráviteľný kód napísaný pomocou klasickej syntaxe funkcií v JavaScripte. A takto vyzerá rovnaký kód, prepísaný pomocou syntaxe šípky:
function getVerifiedToken(selector) ( return getUsers(selector) .then(users => users) .then(verifyUser) .then((používateľ,overenýToken) => ověřenýToken) .catch(err => log(err.stack)); )
Tu musíte venovať pozornosť niekoľkým dôležitým bodom:
  • Stratili sme funkciu a (), pretože naše funkcie spätného volania sú napísané na jednom riadku.
  • Odstránili sme (). Teraz nezalamujú zoznam argumentov, keď je prítomný iba jeden argument (ostatné argumenty prechádzajú ako výnimky; napríklad (...args) => ...).
  • Zbavili sme sa kľúčového slova return. Odstránením () umožňujeme jednoriadkovým šípkovým funkciám vykonávať implicitný návrat (v iných jazykoch sa takéto funkcie často nazývajú funkcie lambda).
Venujme ešte raz pozornosť poslednému bodu. Implicitný návrat sa vyskytuje iba v prípade jednoriadkových funkcií šípok. Keď je funkcia šípky definovaná pomocou (), aj keď ide o samostatný príkaz, nedochádza k žiadnemu implicitnému návratu.
const getVerifiedToken = selector => ( return getUsers() .then(users => users) .then(verifyUser) .then((user, authenticToken) => ověřenýToken) .catch(err => log(err.stack)); )
Tu začína zábava. Keďže naša funkcia má iba jeden operátor, môžeme odstrániť () a kód bude veľmi podobný syntaxi CoffeeScript:
const getVerifiedToken = selector => getUsers() .then(users => users) .then(verifyUser) .then((používateľ, overenýToken) => ověřenýToken) .catch(err => log(err.stack));
A napriek tomu je vyššie uvedený kód napísaný pomocou syntaxe ES2015. (Tiež ma prekvapilo, že sa to skompilovalo perfektne.) Keď hovoríme o funkciách šípok s jedným príkazom, neznamená to, že príkaz nemôže zaberať viac ako jeden riadok, aby sa uľahčilo používanie.

Je tu však jedna významná nevýhoda: odstránením () z funkcií šípok, ako môžeme vrátiť prázdny objekt? Napríklad to isté ()?
const emptyObject = () => (); emptyObject(); // ?
A takto vyzerá celý kód spolu:
funkcia () ( návrat 1; ) () => ( návrat 1; ) () => 1 funkcia (a) ( návrat a * 2; ) (a) => ( návrat a * 2; ) (a) => a * 2 a => a * 2 funkcia (a, b) ( návrat a * b; ) (a, b) => ( návrat a * b; ) (a, b) => a * b funkcia () ( vrátiť argumenty; ) (...argumenty) => argumenty () => () // nedefinované () => (()) // ()

Lexical this Príbeh o tom, ako sa to snažili prepašovať do JavaScriptu, už zapadol prachom. Každá funkcia v JavaScripte nastavuje svoj vlastný kontext. Tento kontext sa na jednej strane dá veľmi ľahko obísť, no na druhej strane je mimoriadne otravný. V príklade nižšie môžete vidieť kód hodín, ktoré aktualizujú údaje každú sekundu pomocou jQuery:
$(".aktuálny-čas").each(funkcia () ( setInterval(funkcia () ( $(this).text(Date.now()); ), 1000); ));
Keď sa pokúsime odkázať na tento prvok DOM špecifikovaný prostredníctvom každého v spätnom volaní setInterval, dostaneme, žiaľ, úplne iné - to, ktoré patrí k spätnému volaniu. Môžete to obísť nastavením premennej that alebo self:
$(".aktuálny-čas").each(function () ( var self = this; setInterval(function () ( $(self).text(Date.now()); ), 1000); ));
Funkcie tučných šípok môžu pomôcť vyriešiť tento problém, pretože nemajú toto:
$(".aktuálny-čas").each(funkcia () ( setInterval(() => $(this).text(Date.now()), 1000); )); A čo argumenty? Jednou z nevýhod funkcií šípok je, že nemajú svoje vlastné premenné argumentov, ako bežné funkcie:
function log(msg) ( const print = () => console.log(arguments); print(`LOG: $(msg)`); ) log("ahoj"); // Ahoj
Zopakujme, že šípkové funkcie nemajú toto a žiadne argumenty. Ak to však vezmete do úvahy, stále môžete získať argumenty odovzdané funkciám šípok pomocou parametrov odpočinku (známych aj ako operátory rozšírenia):
function log(msg) ( const print = (...args) => console.log(args); print(`LOG: $(msg)`); ) log("ahoj"); // LOG: ahoj A čo generátory? Funkcie hrubých šípok nemožno použiť ako generátory. Neexistujú žiadne výnimky ani riešenia. Záver Funkcie tučných šípok sú jedným z dôvodov, prečo tak milujem JavaScript. Je veľmi lákavé začať používať => namiesto funkcie. Videl som celé knižnice, ktoré používajú iba možnosť =>. Nemyslím si však, že je to múdre. Koniec koncov, => má veľa vrtochov a skrytých funkcií. Funkcie šípok odporúčam používať len tam, kde potrebujete novú funkcionalitu:
  • Funkcie s jednoduchými príkazmi, ktoré sa okamžite vrátia;
  • funkcie, ktoré s tým musia pracovať s nadradeným rozsahom.
ES6 dnes Môžete teda využiť výhody ES6 dnes? Používanie transpilátorov sa v posledných rokoch stalo normou. S ich využitím neváhajú ani bežní vývojári, ani veľké firmy.

12 odpovedí

Čo to je

Toto je funkcia šípky. Funkcie šípok sú krátkou syntaxou zavedenou v ECMAscript 6, ktorú možno použiť podobným spôsobom, ako by ste použili výrazy funkcií. Inými slovami, často ich môžete použiť namiesto výrazov ako function (foo) (...) . Majú však niekoľko dôležitých rozdielov. Napríklad nezaväzujú svoje vlastné tieto hodnoty (pozri diskusiu nižšie).

Funkcie šípok sú súčasťou špecifikácie ECMAscript 6. Zatiaľ nie sú podporované vo všetkých prehliadačoch, ale sú čiastočne alebo úplne podporované v Node v. 4.0+ a vo väčšine moderných prehliadačov používaných od roku 2018. (Nižšie je uvedený čiastočný zoznam podporovaných prehliadačov).

Z dokumentácie Mozilly:

Výraz funkcie šípky (známy aj ako funkcia tučnej šípky) má kratšiu syntax ako výraz funkcie a lexikálne viaže hodnotu this (neviaže svoju vlastnú hodnotu this , arguments , super alebo new.target ). Funkcie šípok sú vždy anonymné. Tieto funkčné výrazy sú najvhodnejšie pre nemetódové funkcie a nemožno ich použiť ako konštruktory.

Poznámka o tom, ako to funguje vo funkciách šípok

Jedna z najpohodlnejších funkcií funkcie šípky je ukrytá v texte vyššie:

Funkcia šípky... lexikálne viaže hodnotu tohto (neviaže svoje vlastné toto...)

Zjednodušene to znamená, že funkcia šípky ukladá hodnotu this z jej kontextu a nemá vlastný this . Tradičná funkcia môže viazať túto hodnotu samostatne, v závislosti od toho, ako je definovaná a volaná. To si môže vyžadovať veľa gymnastiky, napríklad seba = toto; atď. na prístup alebo manipuláciu z jednej funkcie v rámci inej funkcie. Viac informácií o tejto téme nájdete vo vysvetleniach a príkladoch v dokumentácii Mozilly.

Príklad kódu

Príklad (aj z dokumentov):

Var a = [ "Sme hore celú noc "do slnka", "Sme hore celú noc, aby sme niečo dostali", "Sme hore celú noc pre dobrú zábavu", "Sme hore celú noc, aby sme sa dostali" lucky" ]; // Tieto dve priradenia sú ekvivalentné: // Stará škola: var a2 = a.map(function(s)( return s.length )); // ECMAscript 6 pomocou šípkových funkcií var a3 = a.map (s => s.length); // a2 aj a3 sa budú rovnať

Poznámky ku kompatibilite

V Node môžete používať funkcie šípok, ale podpora prehliadača nie je úplne správna.

Podpora prehliadača pre túto funkcionalitu sa výrazne zlepšila, ale stále nie je dostatočne rozšírená pre väčšinu aplikácií založených na prehliadači. Od 12. decembra 2017 je podporovaný v aktuálnych verziách:

  • Chrome (v. 45+)
  • Firefox (v. 22+)
  • Edge (vs. 12+)
  • Opera (v. 32+)
  • Prehliadač Android (verzia 47+)
  • Opera Mobile (verzia 33+)
  • Chrome pre Android (verzia 47+)
  • Firefox pre Android (verzia 44+)
  • Safari (verzia 1 0+)
  • iOS Safari (verzia 10.2+)
  • Internet Samsung (v. 5+)
  • Prehliadač Baidu (v. 7. 12+)

Nepodporované v:

  • IE (pred článkom 11)
  • Opera Mini (až do verzie 8.0)
  • Prehliadač Blackberry (do verzie 10)
  • IE Mobile (do verzie 11)
  • UC Browser pre Android (až do verzie 11.4)
  • QQ (až do verzie 1.2)

Viac (a aktuálnejších) informácií nájdete na CanIUse.com (bez pridruženia).

Toto je známe ako funkcia šípky, ktorá je súčasťou špecifikácie ECMAScript 2015...

var foo = ["a", "ab", "abc"]; var bar = foo.map(f => f.length); console.log(bar); // 1,2,3

Kratšia syntax ako predchádzajúca:

// < ES6: var foo = ["a", "ab", "abc"]; var bar = foo.map(function(f) { return f.length; }); console.log(bar); // 1,2,3

Ďalšia úžasná vec je lexikálna toto... Zvyčajne robíte niečo ako:

function Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( var self = this; setInterval(function() ( // toto je Window, nie Foo (), ako by ste mohli očakávať console.log(this); // // preto sme toto priradili k sebe pred setInterval() console.log(self.count); self.count++; ), 1000) ) new Foo();

Ale to sa dá prepísať pomocou šípky takto:

function Foo() ( this.name = meno; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( setInterval(() => ( console.log(this); // console.log(this.count); // 1, 2, 3 this.count++; ), 1000) ) new Foo();

Toto by bol „výraz funkcie šípky“ zavedený v ECMAScript 6.

Pre historické účely (ak sa wiki stránka neskôr zmení) je toto:

Výraz funkcie šípky má kratšiu syntax ako výraz funkcie a lexikálne viaže túto hodnotu. Funkcie šípok sú vždy anonymné.

Tiež známe ako funkcie Fat Arrow Functions. Toto je jednoduchý a jasný spôsob zápisu funkčných výrazov, ako napríklad function() () .

Funkcie šípok môžu eliminovať potrebu funkcií , return a () pri definovaní funkcií. Sú to jednoriadkové výrazy podobné výrazom lambda v Jave alebo Pythone.

Príklad bez parametrov

const queue = ["Dave", "Sarah", "Sharon"]; const dalsiCustomer = () => fronta; console.log(nextCustomer()); // "Dave"

Ak potrebujete vykonať viacero príkazov v rovnakej funkcii šípky, tento príklad vyžaduje, aby ste front uzavreli do zložených zátvoriek () . V tomto prípade nemožno vynechať príkaz návratu.

Príklad s 1 parametrom

const queue = ["Dave", "Sarah", "Sharon"]; const addCustomer = meno => ( queue.push(meno); ); addCustomer("Toby"); console.log(queue); // ["Dave", "Sarah", "Sharon", "Toby"]

Z vyššie uvedeného môžete vynechať ().

Ak existuje jeden parameter, zátvorky () okolo parametra možno vynechať.

Príklad s viacerými parametrami

const addNumbers = (x, y) => x + y console.log(addNumbers(1, 5)); // 6

Užitočný príklad const fruits = [ (názov: "Jablko", cena: 2), (názov: "Banán", cena: 3), (názov: "Hruška", cena: 1) ];

Ak by sme chceli získať cenu každého ovocia v jednom poli, v ES5 by sme mohli urobiť:

Ovocie.mapa(funkcia(ovocie) ( vrátiť ovocie.cena; )); //

V ES6 s novými funkciami šípok to môžeme urobiť stručnejšie:

Ovocie.mapa(ovocie => ovocie.cena); //

Viac informácií o funkciách šípok nájdete.

Kompatibilita prehliadača
  • IE: zatiaľ nie je podporované
  • Edge: 12+ (všetky verzie)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • iOS Safari: 10.2+
  • Prehliadač Android: 56+

Ak chcete získať ďalšie aktuálne informácie o kompatibilite prehliadača, navštívte stránku

Ako povedali iní, ide o novú syntax na vytváranie funkcií.

Tento typ funkcie sa však líši od bežných funkcií:

    Viažu hodnotu tohto . Ako vysvetľuje špecifikácia,

    ArrowFunction nedefinuje lokálne väzby pre argumenty, super, this alebo new.target. Akýkoľvek odkaz na argumenty , super , this alebo new.target v rámci ArrowFunction rieši väzbu v lexikálnom prostredí. Zvyčajne to bude funkčné prostredie okamžite funkciou.

    Aj keď ArrowFunction môže obsahovať odkazy na super, funkčný objekt vytvorený v kroku 4 sa vykonaním MakeMethod nezmení na metódu. ArrowFunction, ktorá odkazuje na super, je vždy obsiahnutá v inej ako šípkovej funkcii a potrebná implementácia super je prístupná cez rozsah, ktorý je zachytený objektom funkcie ArrowFunction.

  • Sú to nekonštruktéri.

    To znamená, že nemajú internú metódu [], a preto ich nemožno napríklad inštanciovať

    Var f = a => a; f(123); // 123 new f(); // TypeError: f nie je konštruktor

Pridanie jednoduchého príkladu CRUD so šípkou

//Funkcia šípky var customers = [ ( meno: "Dave", kontakt: "9192631770" ), ( meno: "Sarah", kontakt: "9192631770" ), ( meno: "Akhil", kontakt: "9928462656" )] , // No Param READ getFirstCustomer = () => ( console.log(this); return customers; ); console.log("Prvý zákazník "+JSON.stringify(getFirstCustomer())); // "Dave" //1 Param SEARCH getNthCustomer = index=>( if(index>customers.length) ( return "No take thing"; ) else( return customers; ) ); console.log("N-tý zákazník je " +JSON.stringify(getNthCustomer(1))); //2params ADD addCustomer = (meno, kontakt)=> customers.push(( "meno": meno, "kontakt":kontakt )); addCustomer("Hitesh","8888813275"); console.log("Pridaný zákazník "+JSON.stringify(zákazníci)); //2 param UPDATE updateCustomerName = (index, newName)=>(customers.name= newName); updateCustomerName(customers.length-1,"HiteshSahu"); console.log("Aktualizovaný zákazník "+JSON.stringify(zákazníci)); //1 param DELETE removeCustomer = (customerToRemove) => customers.pop(customerToRemove); removeCustomer(getFirstCustomer()); console.log("Odstránený zákazník "+JSON.stringify(zákazníci));

Rovnako ako všetky ostatné odpovede, aj toto je súčasťou syntaxe funkcie ES2015. Konkrétne to nie je operátor, je to token token, ktorý oddeľuje parametre od tela: ArrowFunction: ArrowParameters => ConciseBody . Napríklad. (paramy) => ( /* telo */ ) .

V javascripte je symbol => výrazom funkcie šípky. Výraz funkcie šípky nemá vlastnú túto väzbu, a preto ho nemožno použiť ako funkciu konštruktora. Napríklad:

var words = "ahoj z vonkajšieho objektu"; nech obj = ( slová: "ahoj z vnútra objektu", talk1: () => (console.log(toto.slova)), talk2: funkcia () (console.log(toto.slova)) ) obj.talk1( ); // nemá svoju vlastnú väzbu, toto === okno obj.talk2(); // má vlastnú väzbu, toto je obj

Pravidlá používania funkcií šípok:
  • Ak existuje iba jeden argument, môžete zátvorky argumentov vynechať.
  • Ak vrátite výraz a urobíte to na rovnakom riadku, môžete vynechať príkazy () a return

Napríklad:

nech times2 = val => val * 2; // Je na tom istom riadku a vracia výraz, preto sú () potvrdené a výraz sa vracia implicitne // tiež existuje len jeden argument, preto sú zátvorky okolo argumentu vynechané console.log(times2(3));

Nespokojný s inými odpoveďami. Najviac hlasovaná odpoveď dňa 2019/3/13 je vecne nesprávna.

Krátka stručná verzia toho, čo => znamená, je skratka na napísanie funkcie a jej priradenie k aktuálnemu

Const foo = a => a * 2;

Efektívna skratka pre

Const foo = function(a) ( return a * 2; ).bind(this);

Môžete vidieť všetky veci, ktoré boli vyrezané. Nepotrebujeme funkciu , return , .bind(this) , zátvorky ani zátvorky

Trochu dlhší príklad funkcie šípky by mohol byť

Const foo = (šírka, výška) => ( const area = šírka * výška; oblasť návratu; );

Ukazuje, že ak potrebujeme viaceré argumenty funkcií, potrebujeme zátvorky a ak chceme napísať viac ako jeden výraz, potrebujeme zložené zátvorky a explicitný návrat .

Je dôležité pochopiť časť .bind a je to veľká téma. Súvisí to s tým, čo to znamená v JavaScripte.

VŠETKY funkcie majú implicitný parameter nazývaný toto . Ako sa to nastaví pri volaní funkcie, závisí od toho, ako sa funkcia volá.

súhlasiť

Funkcia foo() ( console.log(this); )

Ak to nazývaš ok

Funkcia foo() ( console.log(this); ) foo();

toto bude globálny objekt.

Ak ste v prísnom režime

"používať prísne"; funkcia foo() ( console.log(this); ) foo(); // alebo funkcia foo() ( "použiť prísne"; console.log(this); ) foo();

Bude nedefinované

Môžete to nastaviť priamo pomocou hovoru alebo žiadosti

Funkcia foo(msg) ( console.log(msg, this); ) const obj1 = (abc: 123) const obj2 = (def: 456) foo.call(obj1, "ahoj"); // vypíše Ahoj (abc: 123) foo.apply(obj2, ["ahoj"]); // vytlačí Ahoj (def: 456)

Môžete to nastaviť aj implicitne pomocou bodkového operátora.

Funkcia foo(msg) ( console.log(msg, this); ) const obj = ( abc: 123, bar: foo, ) obj.bar("Hola"); // vytlačí Hola (abc:123, bar: f)

Problém nastáva, keď chcete použiť funkciu ako spätné volanie alebo poslucháč. Vytvárate triedu a chcete priradiť funkciu ako spätné volanie, ktoré pristupuje k inštancii triedy.

Trieda ShowName ( constructor(name, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); // nebude fungovať )); ) )

Vyššie uvedený kód nebude fungovať, pretože keď prvok vyvolá udalosť a zavolá funkciu, hodnota this nebude inštanciou triedy.

Jedným z bežných spôsobov riešenia tohto problému je použitie .bind

Trieda ShowName ( constructor(name, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); ).bind(this); // ( console.log (toto.meno); )); ) )

bind efektívne vytvára novú funkciu. Ak by väzba neexistovala, mohli by ste si takto vytvoriť svoj vlastný

Funkcia bind(fucitonToBind, valueToUseForThis) ( return function(...args) ( functionToBind.call(valueToUseForThis, ...args); )

V starom JavaScripte bez operátora spread by to tak bolo

Funkcia bind(fucitonToBind, valueToUseForThis) ( return function() ( functionToBind.apply(valueToUseForThis, argumenty); )

Pochopenie, že kód vyžaduje pochopenie uzáverov, ale krátka verzia bind vytvára novú funkciu, ktorá vždy volá pôvodnú funkciu s naviazanou hodnotou this. Funkcia šípky robí to isté, pretože ide o skratku na viazanie (toto)

Šípka funkcie, ktorú predstavuje symbol (=>), vám pomáha vytvárať anonymné funkcie a metódy. Výsledkom je kratšia syntax. Nižšie je napríklad jednoduchá funkcia Add, ktorá vráti sčítanie dvoch čísel.

Funkcia Add(num1 , num2)( return num1 + num2; )

Vyššie uvedená funkcia sa skráti použitím syntaxe Arrow, ako je uvedené nižšie.

Vyššie uvedený kód pozostáva z dvoch častí, ako je znázornené na obrázku vyššie:

Vstup: - Táto časť špecifikuje vstupné parametre pre anonymnú funkciu.

Logika: - Táto časť nasleduje za symbolom "=>". Táto časť má logiku skutočnej funkcie.

Mnoho vývojárov verí, že funkcia šípky robí vašu syntax kratšou, jednoduchšou, a preto robí váš kód čitateľným.

Ak veríte vyššie uvedenej vete, dovoľte mi, aby som vás uistil, že ide o mýtus. Ak sa na chvíľu zamyslíte, správne napísaná funkcia s názvom je oveľa čitateľnejšia ako kryptické funkcie vytvorené na jednom riadku pomocou symbolu šípky.

Hlavné použitie funkcie šípky je zabezpečiť, aby sa kód spustil v kontexte volajúcich.

Pozri nižšie uvedený kód, ktorý definuje globálnu premennú "kontext", táto globálna premenná je prístupná vo funkcii "SomeOtherMethod", ktorá sa volá z inej metódy "SomeMethod".

Táto metóda SomeMethod má lokálnu kontextovú premennú. Keďže sa SomeOtherMethod volá z "SomeMethod", očakávame, že zobrazí "miestny kontext", ale zobrazí "globálny kontext".

Var kontext = "globálny kontext"; function SomeOtherMethod())( alert(this.context); ) function SomeOtherMethod())( this.context = "miestny kontext"; SomeOtherMethod(); ) var instance = new SomeMethod();

Ak však hovor nahradíte funkciou šípky, zobrazí sa „miestny kontext“.

Var kontext = "globálny kontext"; function SomeOtherMethod())( this.context = "miestny kontext"; SomeOtherMethod = () => ( alert(this.context); ) SomeOtherMethod(); ) var instance = new SomeMethod();

Odporúčam vám prečítať si tento odkaz (funkcia šípky v JavaScripte), ktorý vysvetľuje všetky kontextové scenáre javascriptu a v ktorých prípadoch sa kontext volajúceho nerešpektuje.

Môžete tiež vidieť demo Šípka funguje s javascriptom v tomto videu YouTube,čo prakticky demonštruje pojem Kontext.