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 klicaFunkcijske 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!
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);
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 OpisNa 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čitiPred 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 operaterjaPušč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 prototipaPuščične funkcije nimajo lastnosti prototipa.
Var Foo = () => (); console.log(Foo.prototype); // nedoločeno
Uporaba ključne besede yieldKljuč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 teloPušč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 literalovUpoš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 vrsticPušč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); SpecifikacijeECMAScript 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 |
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.js | ||||||||||||
Popolna podpora za Chrome 45 | Popolna podpora Edge Da | Popolna podpora za Firefox 22 Opombe Popolna podpora 22Opombe 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 št | Opera Popolna podpora 32 | Safari Popolna podpora 10 | WebView Android Popolna podpora 45 | Chrome Android Polna podpora 45 | Firefox Android Popolna podpora 22 Opombe Popolna podpora 22Opombe 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 32 | Safari iOS Popolna podpora 10 | Samsung Internet Android Polna podpora 5.0 | nodejs Popolna podpora Da |
Popolna podpora za Chrome 58 | Edge? | Firefox Polna podpora 52 | IE Brez podpore št | Opera Popolna podpora 45 | Safari? | WebView Android Popolna podpora 58 | Chrome Android Polna podpora 58 | Firefox Android Popolna podpora 52 | Opera Android Popolna podpora 43 | Safari iOS? | Samsung Internet Android Polna podpora 7.0 | nodejs Popolna podpora Da |
- 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.
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).
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.
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).
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.
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.
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().
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.
- 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).
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