Funkcije puščic Js. O ključni besedi JavaScript “ta”: značilnosti uporabe z razlago. Pravila za uporabo puščičnih funkcij

Postali so zelo modni, vidimo jih v vseh novih člankih. In če jih niste vajeni, boste težko razumeli sodobno (ES6) kodo, ki vsebuje puščične funkcije.

Ta članek ni namenjen temu, da bi vam povedal, kdaj in kako jih uporabiti. Poskušal bom razložiti novo sintakso za tiste, ki jo vidijo prvič. Ali ga uporabljate ali ne, ni pomembno, a prej ali slej ga boste vseeno kje srečali. Zato je bolje razumeti mehaniko te nove sintakse.

Tukaj je majhen primer:

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

Zgornjo kodo lahko zapišemo takole:

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

Ali v v tem primeru, še krajše:

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

Drugi primer uporablja ( ... ) zavite oklepaje, toda ker gre samo za eno vrstico kode, lahko zavite oklepaje izpustite in vrnitev je implicirana, kot je razvidno iz tretjega primera.

En parameter

Če ima puščična funkcija en parameter, lahko oklepaje izpustite:

// Bilo je: someCallBack((rezultati) => ( ... )) // Zdaj: someCallBack(rezultati => ( ... ))

Če pa parametrov ni, morate uporabiti odpirajoče in zapirajoče oklepaje:

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

Funkcije povratnega klica

Funkcijske puščice so še posebej uporabne za povratne klice. Tisti, ki poznajo JavaScript, poznajo njegov leksikalni obseg, ki je precej čeden, vendar lahko naredi takšne trike ( to):

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

Obstaja več različic tega "_this" (kot je "self" ali "that"), vendar je ideja enaka. Pri funkcijah povratnega klica potrebujemo dostop do različice zunanjega obsega, vendar je ideja enaka. Pri funkcijah povratnega klica potrebujemo dostop do različice tega zunanjega obsega, ki je zdaj drugačna od prejšnje, saj govorimo o funkciji povratnega klica.

Z uporabo puščične funkcije, dobimo "block scope" in "this", kar je v obeh primerih isto "this". To pomeni, da je zgornjo kodo mogoče prepisati brez _this = this:

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

"ovitek"

Predstavljajmo si situacijo, kot je v Reactu, kjer dogodek onClick mora klicati doSomething() , (), vendar mora posredovati tudi argumente doSomething() (npr. ID). Ta primer dejansko ne deluje:

Neki uporabnik))

Koda se bo izvajala, vendar bo tehnično poklicala doSomething() takoj, ko se stran naloži. Za rešitev te težave se nekateri razvijalci sklicujejo na funkcijo ovoja:

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

Odsotnost oklepaja v this.onClick pomeni, da je preprosto sklic na funkcijo in ne klic funkcije.

Funkcija onClick() je zdaj nekakšen ovoj za doSomething(). S puščičnimi funkcijami lahko naredite "ovoje" te vrste:

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

Kot alternativo bi lahko uporabili tudi .bind(), ki ne zahteva nobenih ovojov (funkcije puščic ali karkoli):

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

Podpora brskalnika za funkcije puščic

Če potrebujete podporo za brskalnik, razen najnovejše različice Chrome in Firefox, uporaba Transpiler Babel da pretvorite kodo ES6, ki ste jo napisali, v ES5.

ES6 ima nov način ustvarjanja funkcij - z uporabo operatorja Arrow =>. Takšne funkcije imenujemo puščične funkcije. Ponujajo bolj kompaktno sintakso. Nimajo imena in s tem delajo drugače.

Prva stvar, ki jo bomo naredili, je, da zaženemo skript Babel, ki bo spremljal datoteke in ustvaril sveže različice, ko se spremenijo.

Odprite mapo projekta v ukazna vrstica(KS). Vnesite ukaz:

In pritisnite Enter

V mapi src bomo ustvarili datoteko arr.js in jo takoj označili v datoteki index.html

</script>

Najnovejše različice brskalnikov podpirajo funkcije puščic brez transpilacije in moj brskalnik je eden izmed njih.

Napišimo funkcijo, ki sešteje dve števili in vrne njuno vsoto. Pokličimo funkcijo add.

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

V konzoli bomo videli rezultat - 9

Zdaj pa pretvorimo to funkcijo v puščično funkcijo.

Odstranimo besedo funkcija , odstranimo ime funkcije in odstranimo zavite oklepaje ter besedo - return . Po parametrih bomo postavili puščico.

Naj dodamo = (x, y) => x + y; console.log(add(4, 6));

Če pogledate vrsto spremenljivke add z operatorjem typeof:

Console.log(typeof(add));

To je tisto, kar bomo videli v funkcijski konzoli

To pomeni, da so puščične funkcije navadne funkcije. In to lahko preverite tako, da pogledate prevedeno kodo.

"uporabi strogo"; var _typeof = typeof Symbol === "funkcija" && typeof Symbol.iterator === "symbol" ? funkcija (obj) ( vrni typeof obj; ) : funkcija (obj) ( vrni obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj ;); var add = funkcija add(x, y) ( return x + y; ); console.log(add(4, 6)); console.log(typeof add === "undefined" ? "undefined" : _typeof(add));

Vidimo lahko, da je Babel našo kodo spremenil v preprost funkcijski izraz.

Napišimo preprosto funkcijo, ki kvadrira dano število.

Naj dodamo = (x, y) => x + y; console.log(add(4, 6)); console.log(typeof(add)); let square = function(a) ( return a * a; ) console.log(square (4));

Poglejmo v konzolo:

Puščična funkcija bo videti takole:

Naj bo kvadrat = x => x * x;

Če puščična funkcija sprejme samo en parameter, ga ni treba dati v oklepaj!

Napišimo funkcijo, ki sploh ne sprejema parametrov.

Funkcija givNumer () ( vrnitev 33; ) console.log(givNumer ());

Ta funkcija na konzolo preprosto natisne številko 33. Puščica:

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

Ustvarimo funkcijo, ki ne bo vrnila ničesar. Preprosto bo prikazal sporočilo v konzoli brskalnika.

Naj log = funkcija () ( console.log("Hello World!"); ); log();

stikalo:

Naj log = () => console.log("Hello World!!!"); log();

Ustvarimo funkcijo, katere telo bo sestavljeno iz dveh črt.

Funkcija bo imela dva parametra. Ustvarimo spremenljivko v telesu funkcije. Po tem bomo vrnili rezultat.

Naj mult = funkcija (a, b) ( naj rezultat = a * b; vrne rezultat; ) console.log(mult (4, 5));

Če je v puščični funkciji več vrstic, so potrebni zaviti oklepaji - ()! In ne pozabite definirati, kaj ta funkcija vrne s ključno besedo return

stikalo:

Naj mult = (a, b) => ( naj rezultat = a * b; vrne rezultat; ) console.log(mult (4, 5));

Zdaj pa ustvarimo funkcijo, ki vrne literal objekta:

Naj literal = funkcija () ( return ( ime: "John"); ) console.log (literal ());

V konzoli bomo videli:

Zdaj pa poskusimo ustvariti puščično funkcijo, ki bo vrnila literal objekta.

Ne smemo pozabiti, da če puščična funkcija vrne objektni literal, so potrebni oklepaji - ()

Puščična funkcija, ki vrne literal predmeta:

Naj literal = () => ((ime: "John")); console.log(literal());

Zdaj pa poskusimo uporabiti puščično funkcijo kot IIFE – takojšnji funkcijski izraz

Skratka, to je funkcija, ki se izvede takoj po deklaraciji

Videti je takole:

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

Puščična funkcija IIFE bo videti takole:

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

Pomembna lastnost puščičnih funkcij je, da mora puščica priti takoj za parametri!

Ne morete ga preprosto vzeti in ga premakniti v vrstico spodaj. Poročilo bo o napaki!

Praktična uporaba puščičnih funkcij. Puščične funkcije so zelo priročne za uporabo z nizi.

Ustvarimo niz z nekaj številkami in ga poimenujmo numbers. Mislim, da veste, da imajo nizi uporabne metode, ki vam omogočajo ponavljanje po nizu, njegovo filtriranje itd.

Izračunajmo vsoto vseh spremenljivk polja. Da bi to naredil, bom deklariral drugo spremenljivko - naj bo vsota = 0;

Uporabimo metodo forEach(), ki jo ima vsaka matrika, ponovili bomo elemente in sešteli vsoto.

Naj bodo števila = ; naj bo vsota = 0; numbers.forEach(function(num) ( sum += num; )); console.log(vsota);

V konzoli bomo videli 55. Spremenimo to funkcijo v puščično funkcijo: numbers.forEach(num => sum += num); console.log(vsota);

Tako je tisto, kar nam je prej vzelo tri vrstice, zdaj eno.

Vsak element matrike lahko tudi kvadriramo.

Naj bo na kvadrat = numbers.map(n => n * n); console.log(na kvadrat);

Puščične funkcije in to . Da bi to naredil, bom ustvaril literal objekta, ki ga bom shranil v spremenljivko oseba.

Objekt osebe bo imel lastnost name z vrednostjo 'Bob' in lastnost greet z vrednostjo 'Greet'. Pozdrav bomo natisnili v konzolo in pogledali tudi namen tega.

Let person = ( name: "Bob", greet: function () ( console.log("Pozdravljeni! Ime mi je " + this.name); console.log(this); ) ); person.greet();

V konzoli brskalnika bomo videli pozdrav in sam predmet osebe.

Zdaj bomo funkcijo zamenjali s puščico in videli, kaj se s tem zgodi.

Let person = ( name: "Bob", greet: () => ( console.log("Pozdravljeni! Moje ime je " + this.name); console.log(this); ) ); person.greet();

Zdaj nismo dobili vrednosti imena in vrednost tega je okno!

Ampak zakaj? Bistvo je, da je vrednost tega vzeta iz konteksta, v katerem je deklarirana funkcija. ! Ne glede na to, kje bo to funkcijo opravljal. To se vidi na sliki:

Imamo program.

Zaenkrat v njem ni ničesar razen okenskega objekta. Dodan predmet osebe. Upoštevajte, da za metodo uporabljamo puščično funkcijo. Kot smo rekli, bo vrednost tega vzeta iz konteksta. Kontekst je okolje. V tem primeru bo okolje predmeta osebe, vse njegove lastnosti in metode okenski objekt. In če je vrednost tega vzeta iz konteksta, potem se bo to nanašalo na okenski objekt.

Če pogledamo običajno funkcijo, potem vemo, da se to nanaša na sam predmet osebe. Lahko se vprašate, zakaj je vrednost tega v puščičnih funkcijah vzeta iz konteksta? In odgovor je zelo preprost – naredili so tako! :-) Bistvo je, da so bile puščične funkcije ustvarjene za reševanje problemov v drugačni situaciji. Poglejmo si primer. Da bi videli težavo, se bomo vrnili k naši funkciji puščice.

Let person = ( name: "Bob", greet: function () ( console.log("Pozdravljeni! Ime mi je " + this.name); console.log(this); ) );

Predstavljajmo si, da je naš Bob precej zaposlen in potrebuje nekaj sekund, da dokonča svoje delo. Počakajte 2 sekundi. simuliramo s funkcijo setTimeout(); .Ta funkcija vzame funkcijo kot prvi parameter in število milisekund za čakanje kot drugi parameter.

Let person = ( name: "Bob", greet: function () ( setTimeout(function () ( console.log("Pozdravljeni! Ime mi je " + this.name); console.log(this); ), 2000) ;) ); person.greet();

Če imate izkušnje z JavaScriptom, mislim, da razumete, v čem je težava. Kakorkoli že, poglejmo, kaj se bo zgodilo v brskalniku. Točno dve sekundi kasneje bomo to sliko videli v brskalniku.

Ampak zakaj? Če pogledate našo kodo, je logično domnevati. da se to nanaša na objekt osebe, saj uporabljamo običajno funkcijo. Stvar je v tem, da setTimeout() pripada objektu window. Če to zapišete takole: window.setTimeout(), na kaj se potem po vašem mnenju to nanaša? In v konzoli bomo dobili enak rezultat! V ES5 obstaja več načinov za rešitev te težave. Ogledali si bomo najpogostejšega: pred setTimeout() bom deklariral drugo spremenljivko in jo dodelil kot vrednost. In zdaj bomo v telesu funkcije namesto tega navedli to.

Let person = ( name: "Bob", greet: function () ( let that = this; setTimeout(function () ( console.log("Pozdravljeni! Ime mi je " + that.name); console.log(that) ; ), 2000); ) ); person.greet();

Zdaj bo zaradi zaprtja funkcija, ki jo pošljemo v setTimeout(), imela dostop do spremenljivke that, katere vrednost bo this , to je v tem primeru objekt osebe.

Zaradi jasnosti si lahko ogledate, na kaj se nanaša naše to in to.

Let person = ( name: "Bob", greet: function () ( let that = this; setTimeout(function () ( console.log("Pozdravljeni! Moje ime je " + that.name); console.log("It je moje To = " + to); console.log("To je moje To = " + to); ), 2000); ) ); person.greet();

V konzoli bomo videli potrditev:

Vidimo, da bo to okenski objekt - To = , to pa bo naš objekt osebe - To = .

V ES6 lahko preprosto uporabimo puščično funkcijo za rešitev tega problema.

Let person = ( name: "Bob", greet: function () ( setTimeout(() => ( console.log("Pozdravljeni! Ime mi je " + this.name); console.log("To je moj To = " + to); ), 2000); ) ); person.greet();

Posledično bomo v konzoli videli:

IN grafični primer za puščično funkcijo bo kontekst predmet osebe in ne objekta okna. zato se bo to nanašalo na osebo.

Poleg kompaktne sintakse so bile uvedene puščične funkcije za reševanje težav, kot so te.

Za referenco si lahko ogledate, kako je Babel to rešil

Var person = ( name: "Bob", greet: function greet() ( var _this = this; setTimeout(function () ( console.log("Pozdravljeni! Ime mi je " + _this.name); console.log(" To je moje To = " + _to); ), 2000); ) ); person.greet(); Babel je uporabil isto metodo, kot smo jo uporabili v ES5. Edina razlika je v tem, da smo mi spremenljivko poimenovali tako, Babel pa jo je imenoval - _this. Zahvaljujoč zaprtju bo imela funkcija, ki jo pošljemo v setTimeout, dostop do spremenljivke _this in posledično do objekta osebe.

Mislim, da je najtežji del tega dela razumeti, kako delujejo zaprtja.

Še nekaj funkcij puščičnih funkcij:
Več informacij o ES6 in funkcijah puščic si lahko ogledate v moji objavi

Pozdravljeni vsi skupaj! V tem članku si bomo ogledali, katere funkcije puščic so v ES6 in kako jih uporabljati.

Puščične funkcije so funkcije, ki so zapisane z uporabo puščičnega operatorja (=>).

Takoj poglejmo primer:

Naj dodamo = (x, y) => x + y;
console.log(add(5, 2));

Kot rezultat izvajanja te funkcije bomo v konzoli videli številko 7.

Najprej podamo argumente v oklepajih, nato postavimo znak puščice in nato napišemo kodo same funkcije. V našem primeru preprosto vzame dve številki in ju sešteje. V teoriji je to enako kot izraz funkcije v ES5. Če uporabljate Babel ali podobne prevajalnike, bodo najverjetneje napisali nekaj takega:

Var add = funkcija add(x, y) (
vrni x + y;
};

Če vaša funkcija sprejme samo en parameter, oklepaji niso obvezni.

Naj bo kvadrat = x => x*x;

Ta funkcija sprejme samo en argument in kvadrira dano število.

Funkcija brez parametrov:

Naj func = () => 77;

Če vaša funkcija vsebuje več vrstic, morate, prvič, uporabiti zavite oklepaje, in drugič, obvezno napišite, kaj funkcija vrne, tj. uporabite ključno besedo return.

Naj pomnožimo = (x, y) => (
naj bo rezultat = x*y;
vrni rezultat;
};

Če morate vrniti literal objekta, ga morate zaviti v oklepaje:

Naj getObject = () => (( znamka: "BMW" ));

Funkcija samopriklica je videti takole:

Puščični funkcijski izraz je sintaktično kompaktna alternativa regularnemu funkcijskemu izrazu, čeprav brez lastnih vezav na ključne besede this, arguments, super ali new.target. Izrazi puščične funkcije niso primerni kot metode in jih ni mogoče uporabiti kot konstruktorje.

Sintaksa Osnovna sintaksa (param1, param2, …, paramN) => ( izjave ) (param1, param2, …, paramN) => izraz // enakovredno: => ( povratni izraz; ) // Oklepaji so neobvezni, če obstaja samo eno ime parametra: (singleParam) => ( izjave ) singleParam => ( izjave ) // Seznam parametrov za funkcijo brez parametrov mora biti zapisan s parom oklepajev. () => ( izjave ) Napredna sintaksa // Oklepajte telo funkcije, da vrnete dobesedni izraz objekta: params => ((foo: bar)) // Podprti so ostali parametri in privzeti parametri (param1, param2, ...rest) => ( izjave ) (param1 = defaultValue1, param2, …, paramN = defaultValueN) => ( izjave ) // Podprto je tudi destrukturiranje znotraj seznama parametrov var f = ( = , (x: c) = (x: a + b)) => a + b + c; f(); // 6 Opis

Na uvedbo puščičnih funkcij sta vplivala dva dejavnika: potreba po krajših funkcijah in obnašanje ključne besede this.

Krajše funkcije var elements = [ "Hydrogen", "Helium", "Lithium", "Beryllium" ]; // Ta stavek vrne matriko: elements.map (function(element) ( return element.length; )); // Zgornjo navadno funkcijo lahko zapišemo kot puščično funkcijo pod elements.map((element) => ( return element.length; )); // // Če obstaja samo en parameter, lahko odstranimo okoliške oklepaje elements.map (element => ( return element.length; )); // // Ko je edini stavek v puščični funkciji `return`, lahko odstranimo `return` in odstranimo // okoliške zavite oklepaje elements.map(element => element.length); // // V tem primeru, ker potrebujemo samo lastnost dolžine, lahko uporabimo parameter za destrukturiranje: // Upoštevajte, da `length` ustreza lastnosti, ki jo želimo dobiti, medtem ko je // očitno neposebna `lengthFooBArX` samo ime spremenljivke, ki jo je mogoče spremeniti // v poljubno veljavno ime spremenljivke, ki jo želite elements.map ((( length:lengthFooBArX )) => lengthFooBArX); // // To dodelitev parametrov destrukturiranja lahko tudi zapišemo, kot je prikazano spodaj. Vendar upoštevajte, da // v tem primeru izmišljeni lastnosti ne dodeljujemo vrednosti `length`. Namesto tega se kot lastnost, ki jo želimo pridobiti iz predmeta, uporablja samo ime literala // spremenljivke `length`. elements.map ((( dolžina )) => dolžina); // Tega ni treba ločiti

Pred puščičnimi funkcijami je vsaka nova funkcija definirala lastno vrednost te vrednosti glede na to, kako je bila funkcija poklicana:

  • Nov objekt v primeru konstruktorja.
  • nedefinirano v klicih funkcij v strogem načinu.
  • Osnovni objekt, če je bila funkcija poklicana kot "metoda objekta".

To se je izkazalo za manj kot idealno pri objektno usmerjenem slogu programiranja.

Funkcija Person() ( // Konstruktor Person() definira `this` kot primerek samega sebe. this.age = 0; setInterval(function growUp() ( // V nestriktnem načinu funkcija growUp() definira ` this` // kot globalni objekt (ker je tam, kjer se izvaja growUp().), // ki je drugačen od `this` // definiranega s konstruktorjem Person(). this.age++; ), 1000) ; ) var p = nova oseba();

V ECMAScript 3/5 je bilo to težavo mogoče popraviti z dodelitvijo vrednosti v tem spremenljivki, ki jo je bilo mogoče zapreti.

Funkcija Person() ( var that = this; that.age = 0; setInterval(function growUp() ( // Povratni klic se nanaša na spremenljivko `that`, katere // vrednost je pričakovani objekt. that.age++; ) , 1000); ) "uporabi strogo"; var obj = (a: 10); Object.defineProperty(obj, "b", ( get: () => ( console.log(this.a, typeof this.a, this); // nedefinirano "nedefinirano" okno (...) (ali globalno object) vrne this.a + 10; // predstavlja globalni objekt "Window", zato "this.a" vrne "nedefinirano" ) ));

Uporaba novega operaterja

Puščičnih funkcij ni mogoče uporabiti kot konstruktorje in bodo pri uporabi z new vrgle napako.

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

Uporaba lastnosti prototipa

Puščične funkcije nimajo lastnosti prototipa.

Var Foo = () => (); console.log(Foo.prototype); // nedoločeno

Uporaba ključne besede yield

Ključne besede yield ni dovoljeno uporabljati v telesu puščične funkcije (razen če je to dovoljeno v funkcijah, ki so dodatno ugnezdene znotraj nje). Posledično puščičnih funkcij ni mogoče uporabiti kot generatorje.

Funkcijsko telo

Puščične funkcije imajo lahko "jedrnato telo" ali običajno "blok telo".

V jedrnatem telesu je podan le izraz, ki postane implicitna vrnjena vrednost. V telesu bloka morate uporabiti eksplicitni stavek return.

Var func = x => x * x; // jedrnata sintaksa telesa, implicitna "vrnitev" var func = (x, y) => ( return x + y; ); // s telesom bloka, potreben ekspliciten "vrnitev".

Vrnitev objektnih literalov

Upoštevajte, da vračanje objektnih literalov z jedrnato sintakso telesa params => (objekt:literal) ne bo delovalo po pričakovanjih.

Var func = () => ( foo: 1 ); // Klic func() vrne nedefinirano! var func = () => ( foo: funkcija() () ); // SyntaxError: stavek funkcije zahteva ime

To je zato, ker je koda znotraj oklepajev (()) razčlenjena kot zaporedje stavkov (tj. foo se obravnava kot oznaka, ne kot ključ v literalu objekta).

Objektni literal morate zaviti v oklepaje:

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

Prelomi vrstic

Puščična funkcija ne sme vsebovati preloma vrstice med svojimi parametri in puščico.

Var func = (a, b, c) => 1; // SyntaxError: pričakovan izraz, dobil "=>"

Vendar pa je to mogoče spremeniti tako, da prelom vrstice postavite za puščico ali uporabite oklepaje/oklepaje, kot je prikazano spodaj, da zagotovite, da koda ostane lepa in puhasta. Med argumente lahko postavite tudi prelome vrstic.

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; // ni bila vržena SyntaxError

Vrstni red razčlenjevanja

Čeprav puščica v puščični funkciji ni operator, imajo puščične funkcije posebna pravila za razčlenjevanje, ki drugače vplivajo na prednost operatorja v primerjavi z običajnimi funkcijami.

Naj povratni klic; povratni klic = povratni klic || funkcija(); // ok povratni klic = povratni klic || () => (); // SyntaxError: neveljavni argumenti puščične funkcije povratni klic = povratni klic || (() => ()); // v redu

Več primerov // Funkcija prazne puščice vrne nedefinirano let empty = () => (); (() => "foobar")(); // Vrne "foobar" // (to je izraz takoj priklicane funkcije) var simple = a => a > 15 ? 15: a; preprosto (16); // 15 preprost(10); // 10 let max = (a, b) => a > b? a: b; // Enostavno filtriranje nizov, preslikava, ... var arr = ; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // var double = arr.map(v => v * 2); // // Bolj jedrnate obljubne verige promise.then(a => ( // ... )).then(b => ( // ... )); // Puščične funkcije brez parametrov, ki jih je vizualno lažje razčleniti setTimeout(() => ( console.log("Zgodim se prej"); setTimeout(() => ( // globlja koda console.log("Zgodim se pozneje") ; ), enajst); Specifikacije Komentar stanja specifikacije
ECMAScript 2015 (6. izdaja, ECMA-262)
Standardno Začetna definicija.
Najnovejši osnutek ECMAScript (ECMA-262)
Definicija "definicij puščičnih funkcij" v tej specifikaciji.
Osnutek
Združljivost brskalnika

Tabela združljivosti na tej strani je ustvarjena iz strukturiranih podatkov. Če želite prispevati k podatkom, obiščite https://github.com/mdn/browser-compat-data in nam pošljite zahtevo za vleko.

Posodobite podatke o združljivosti na GitHub

Namizni mobilni strežnik Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome za Android Firefox za Android Opera za Android Safari na iOS Samsung Internet Node.jsPuščične funkcije Končna vejica v parametrih
Popolna podpora za Chrome 45Popolna podpora Edge DaPopolna podpora za Firefox 22

Opombe

Popolna podpora 22

Opombe

Opombe Pred Firefoxom 39 je bil zaključek vrstice (\n) nepravilno dovoljen za argumenti puščične funkcije. To je bilo popravljeno zaradi skladnosti s specifikacijo ES2015 in kodo, kot je () \n =>
IE Brez podpore štOpera Popolna podpora 32Safari Popolna podpora 10WebView Android Popolna podpora 45Chrome Android Polna podpora 45Firefox Android Popolna podpora 22

Opombe

Popolna podpora 22

Opombe

Opombe Začetna implementacija puščičnih funkcij v Firefoxu je samodejno naredila stroge. To je bilo spremenjeno od Firefoxa 24. Uporaba "use strict"; je zdaj potrebno. Opombe Pred Firefoxom 39 je bil zaključek vrstice (\n) nepravilno dovoljen za argumenti puščične funkcije. To je bilo popravljeno zaradi skladnosti s specifikacijo ES2015 in koda, kot je () \n => (), bo zdaj vrgla SyntaxError v tej in novejših različicah.
Opera Android Popolna podpora 32Safari iOS Popolna podpora 10Samsung Internet Android Polna podpora 5.0nodejs Popolna podpora Da
Popolna podpora za Chrome 58Edge?Firefox Polna podpora 52IE Brez podpore štOpera Popolna podpora 45Safari?WebView Android Popolna podpora 58Chrome Android Polna podpora 58Firefox Android Popolna podpora 52Opera Android Popolna podpora 43Safari iOS?Samsung Internet Android Polna podpora 7.0nodejs Popolna podpora Da
Legenda Popolna podpora Popolna podpora Brez podpore Ni podpore Združljivost neznana Združljivost neznana Glejte opombe o izvedbi. Glejte opombe o izvedbi.
  • Vadnica

Eden najbolj zanimivih delov novega standarda ECMAScript 6 so funkcije puščic. Puščične funkcije so, kot pove že ime, definirane z novo sintakso, ki uporablja puščico => . Vendar pa se poleg odlične sintakse puščične funkcije od tradicionalnih funkcij razlikujejo še na druge načine:

  • Beksikalna vezava. Vrednote posebne spremenljivke argumenti this , super in niso določeni s tem, kako so bile poklicane puščične funkcije, temveč s tem, kako so bile ustvarjene.
  • Nespremenljivo to , super in argumenti . Vrednosti teh spremenljivk znotraj puščičnih funkcij ostanejo vseskozi nespremenjene življenski krog funkcije.
  • Funkcij puščic ni mogoče uporabiti kot konstruktor in vržejo napako, če se uporabljajo z operatorjem new.
  • Nerazpoložljivost »izvorne« vrednosti spremenljivke argumentov.
Razlogov za uvedbo teh razlik je bilo več. Prvi je, da se povezovanje v JavaScriptu uporablja precej pogosto. Pri uporabi tradicionalnih funkcij je zelo enostavno izgubiti pravilno to vrednost, kar lahko povzroči nepričakovane posledice. Drugi razlog je, da bodo motorji JS zaradi teh omejitev lahko enostavno optimizirali izvajanje puščičnih funkcij (v nasprotju s tradicionalnimi funkcijami, ki jih je mogoče uporabiti kot konstruktor in jih je mogoče prosto spreminjati posebne spremenljivke).


Opomba: Ta članek je kompilacija brezplačnega prevoda članka Razumevanje puščičnih funkcij ECMAScript 6 in branja najnovejšega osnutka specifikacije (20. januar 2014 Osnutek Rev. 22).

Sintaksa Na splošno sintaksa puščičnih funkcij izgleda takole:

Var fun = (x) => x;
Je zelo podobna podobni sintaksi v jezikih, kot so Scala, CoffeeScript in sintaksi lambda izrazov iz C#.

Sintaksa puščičnih funkcij se lahko razlikuje glede na to, kako deklarirate funkcijo. Deklaracija se vedno začne s seznamom argumentov, ki mu sledita puščica in telo funkcije. Tako seznam argumentov kot telo funkcije imata lahko različne oblike, odvisno od tega, kaj pišete.

En parameter Deklaracija puščične funkcije, ki sprejme en argument in ga preprosto vrne, je zelo preprosta:

Var odraža = vrednost => vrednost; // enakovredno varrefref = funkcija(vrednost) ( vrnjena vrednost; )
Če ima puščična funkcija samo en argument, jo je mogoče deklarirati brez oklepajev. Tudi telo funkcije, ki sledi puščici, morda nima zavitih oklepajev in ne sme vsebovati ključne besede return.

Več parametrov Če pa želite deklarirati več kot en parameter, morate seznam parametrov priložiti v oklepajih:

Var sum = (num1, num2) => num1 + num2; // enakovredno var sum = function(num1, num2) ( return num1 + num2; );
Funkcija vsote preprosto doda dva argumenta. Edina razlika od prejšnjega primera je prisotnost oklepajev in vejice (tako kot pri tradicionalnih funkcijah).

Brez parametrov Podobno mora imeti funkcija brez argumentov prazen seznam parametrov v oklepajih:

Vsota spremenljivk = () => 1 + 2; // enakovredno var sum = function() ( return 1 + 2; );

Tradicionalna sintaksa telesa funkcije Tradicionalno sintakso funkcije lahko uporabite za telo puščične funkcije, če vsebuje več kot en izraz. To pomeni, da funkcijo zavijete v zavite oklepaje in dodate ključno besedo return:

Var sum = (num1, num2) => ( return num1 + num2; ) // enakovredno var sum = function(num1, num2) ( return num1 + num2; );
Telo funkcije bo obdelano na povsem enak način kot klasične funkcije, razen vrednosti posebne spremenljivke to , super in argumenti bodo ovrednoteni drugače.

Objektni literal Ločeno je treba omeniti, da mora biti telo funkcije, ki ne vsebuje zavitih oklepajev in preprosto vrne predmetni literal, v oklepajih:

Var getTempItem = id => (( id: id, name: "Temp" )); // enakovredno var getTempItem = function(id) ( return ( id: id, name: "Temp" ) );
Če objektni literal postavite v oklepaj, razčlenjevalniku poveste, da zavit oklepaj ni začetek tradicionalne sintakse za telo funkcije, ampak začetek literala.

Spremenljivo število parametrov Ker objekt »native« argumentov ni na voljo znotraj puščične funkcije (vrednost argumentov je leksikalno povezana z vrednostjo argumentov tradicionalne funkcije, znotraj katere je bila deklarirana puščična funkcija), potem za puščične funkcije s spremenljivo število parametrov, iz katerih morate uporabiti preostali vzorec destrukturiranje vzorcev. primer:

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

Predloga za destrukturiranje kot parameter Za namene tega članka ne upoštevamo vzorcev destrukturiranja - o njih lahko preberete v članku Pregled ECMAScript 6, naslednje različice JavaScripta, čeprav so te informacije delno zastarele.

Kot lahko vidite iz prejšnjega primera, morate kljub temu, da ima puščica samo en argument, pri uporabi uporabiti oklepaje destrukturiranje vzorcev kot edini parameter funkcije. Primeri z drugimi predloge:

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

Uporaba puščičnih funkcij Nastavitev konteksta Eden pogostih scenarijev v JavaScriptu je nastavitev pravilne vrednosti this znotraj funkcije (povezovanje). Ker je vrednost tega mogoče spremeniti, odvisno od konteksta, v katerem se funkcija izvaja, je mogoče pomotoma delovati na en predmet, ko ste mislili nekaj povsem drugega. Poglejte naslednji primer:

Var pageHandler = ( id: "123456", init: function() (document.addEventListener("click", function(event) ( this.doSomething(event.type); // error )); ), doSomething: function( type) ( console.log("Handling " + type + " for " + this.id) ) );
V zgornji kodi bi moral objekt pageHandler obravnavati klike na strani. Metoda init() priloži obravnavo želenemu dogodku, ki interno pokliče this.doSomething(). Vendar koda ne bo delovala pravilno. Sklic na this.doSomething() ni veljaven, ker kaže na objekt dokumenta znotraj obdelovalnika dogodkov namesto na predvideni pageHandler. Če poskusite zagnati to kodo, boste prejeli napako, ker objekt dokumenta nima metode doSomething.

To vrednost lahko povežete s predmetom pageHandler z uporabo handleEvent ali s klicem standardne metode bind() v funkciji:

Var pageHandler = ( id: "123456", init: function() (document.addEventListener("klik", (funkcija(dogodek) ( this.doSomething(event.type); // napaka)).bind(this)) ; ), doSomething: function(type) ( console.log("Handling " + type + " for " + this.id) ) );
Zdaj koda deluje, kot je predvideno, vendar je videti bolj okorna. Poleg tega s klicem bind(this) vsakič, ko ustvarite novo funkcijo, katere ta vrednost je povezana z vrednostjo pageHandler, vendar koda deluje, kot ste nameravali.

Puščične funkcije rešujejo težavo na bolj eleganten način, ker uporabljajo leksikalno vezavo za vrednost this (kot tudi super in argumente), njena vrednost pa je določena z vrednostjo this na lokaciji, kjer je bila puščična funkcija ustvarjena. Na primer:

Var pageHandler = ( id: "123456", init: function() (document.addEventListener("click", event => this.doSomething(event.type)); ), doSomething: function(type) ( console.log( "Upravljanje " + tip + " za " + this.id) ) );
V tem primeru je obravnava puščična funkcija, ki kliče this.doSomething() . Vrednost tega bo enaka kot v funkciji init(), koda pa v v tem primeru bo deloval pravilno, podobno tistemu, ki je uporabil bind(). Ne glede na to, ali klic this.doSomething() vrne vrednost ali ne, izraza znotraj telesa puščične funkcije ni treba zapisati v zavite oklepaje.

Poleg tega je zgornji primer učinkovitejši od klica bind(), ker je enak naslednji kodi za brskalnik:

Var pageHandler = ( id: "123456" , init: function() ( var self = this; document.addEventListener("click", function(event) ( return self.doSomething(event.type) )); ) , doSomething: funkcija(tip) ( console.log("Obdelava " + tip + " za " + this.id) ) );
To pomeni, da do ustvarjanja ne pride nova funkcija, kot je to v primeru klica bind().

»Premetavanje« konteksta med več klici Očitno lahko eno puščično funkcijo ugnezdite v drugo in s tem »vržete« to vrednost skozi njih:

Var obj = ( arr1: , arr2: ["a", "b", "c"] , združi: funkcija(a, b)( vrni a + "|" + b ) , presečišče: funkcija() ( vrni to .arr1.reduce((sum, v1) => // puščična funkcija 1 this.arr2.reduce((sum, v2) => ( // puščična funkcija 2 sum.push(this.concatenate(v1, v2)) return vsota; ) , vsota) , ) ) ); var arrSum = obj.intersection();//["1|a", "1|b", "1|c", "2|a", "2|b", "2|c", "3 |a", "3|b", "3|c"]

Uporaba kot argument Zaradi kratke sintakse puščičnih funkcij so idealni kandidati za posredovanje kot argumentov drugim klicem funkcij. Na primer, če želite razvrstiti matriko, bi običajno napisali nekaj takega:

Var rezultat = values.sort(function(a, b) ( return a - b ));
Precej podrobno za preprosto operacijo. Primerjaj s kratkim zapisom za puščično funkcijo:

Var rezultat = values.sort((a, b) => a - b);
Uporabo metod, kot so array(), map(), reduce() in tako naprej, je mogoče poenostaviti s sintakso kratke puščične funkcije.

Druge funkcije puščičnih funkcij Čeprav se puščične funkcije razlikujejo od tradicionalnih funkcij, imajo nekaj skupnih lastnosti:
  • Operator typeof bo vrnil "function" za puščično funkcijo
  • Puščična funkcija je tudi primerek »razreda« funkcije, zato bo instanceof deloval enako kot tradicionalna funkcija
  • Še vedno lahko uporabljate metode call(), apply() in bind(), vendar ne pozabite, da ne bodo vplivale na vrednost tega
  • Uporabite lahko metodo toMethod(), vendar ne bo spremenila vrednosti super ( metoda toMethod() je bila predstavljena v es6 in ni zajeta v tem članku).
Pomembna razlika od tradicionalnih funkcij je, da bo poskus klica puščične funkcije z uporabo novega operatorja povzročil napako med izvajanjem. Povzetek Puščične funkcije so ena najzanimivejših novosti v ECMAScriptu 6, ki bo zaradi jedrnate sintakse definicije poenostavila prenos funkcij kot vrednosti parametra v drugo funkcijo.

Jedrnata sintaksa vam bo omogočila, da zapletene stvari pišete še bolj zapleteno na preprostejši način. Na primer, takole bo videti generator identifikatorjev (ki je na es5 videti veliko bolj podrobno):

Naj bo idGen = (start = 0, id = start, reset = (newId = start) => id = newId, next = () => id++) => ((reset, next)); naj gen = idGen(100); console.log(gen.next(), gen.next(), gen.reset(10), gen.next());//100 101 10 10
In leksikalna vezava bo zaprla enega največjih virov bolečine in frustracij za razvijalce, izboljšala pa bo tudi zmogljivost zaradi optimizacije na ravni motorja js.


Če želite preizkusiti funkcije puščic, lahko zgornje primere zaženete v konzoli Firefox, ki je vklopljena ta trenutek(02.2014 FF28) skoraj v celoti podpira puščične funkcije (FF28 nepravilno izračuna vrednost argumentov).

Preizkusite lahko tudi funkcije puščic in druge funkcije es6 v ​​spletnem prevajalniku Traceur.

Oznake: dodajte oznake