Js funkcije strelice. O JavaScript ključnoj riječi "ovaj": karakteristike upotrebe sa objašnjenjima. Pravila za korištenje funkcija strelica

Postali su vrlo moderni, vidimo ih u svim novim člancima. A, ako niste navikli na njih, teško ćete razumjeti moderni (ES6) kod koji sadrži funkcije strelice.

Ovaj članak nije namijenjen da vam kaže kada i kako ih koristiti. Pokušaću samo da objasnim novu sintaksu za one koji je vide prvi put. Da li ga koristite ili ne, nije važno, ali prije ili kasnije ćete ga ipak negdje naići. Zato je bolje razumjeti mehaniku ove nove sintakse.

Evo malog primjera:

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

Gornji kod se može napisati ovako:

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

Ili, u ovom slučaju, još kraće:

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

Drugi primjer koristi ( ... ) vitičaste zagrade, ali pošto je to samo jedan red koda, vitičaste zagrade se mogu izostaviti i povrat se podrazumijeva, kao što se vidi u trećem primjeru.

Jedan parametar

Kada funkcija strelice ima jedan parametar, zagrade se mogu izostaviti:

// Bio: someCallBack((rezultati) => ( ... )) // Sada: someCallBack(rezultati => ( ... ))

Ali, ako nema parametara, morate koristiti otvaranje i zatvaranje zagrada:

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

Funkcije povratnog poziva

Strelice funkcija su posebno korisne za povratne pozive. Oni koji poznaju JavaScript su upoznati sa njegovim leksičkim opsegom, koji je prilično uredan, ali može raditi trikove poput ovog ( ovo):

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

Postoji nekoliko varijacija ovog "_ovo" (kao što je "ja" ili "ono"), ali ideja je ista. U funkcijama povratnog poziva potreban nam je pristup verziji vanjskog opsega, ali ideja je ista. U funkcijama povratnog poziva, potreban nam je pristup verziji ovog vanjskog opsega, koja je sada drugačija od prije budući da govorimo o funkciji povratnog poziva.

Korišćenjem funkcije strelica, dobijamo "blok opseg" i "ovo", što je isto "ovo" u oba slučaja. To znači da se gornji kod može prepisati bez _this = this:

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

"Omot"

Zamislimo situaciju kao u Reactu, gdje je događaj onClick treba pozvati doSomething() , (), ali također treba proslijediti argumente doSomething() (npr. ID). Ovaj primjer zapravo ne radi:

Neki korisnik)))

Kôd će se pokrenuti, ali tehnički će pozvati doSomething() odmah kada se stranica učita. Da bi riješili ovaj problem, neki programeri se pozivaju na funkciju omotača:

Const User = React.createClass(function() ( render: function() (vrati nekog korisnika), onClick: function() (doSomething(this.props.userId); ) ))

Odsustvo zagrade u this.onClick znači da je to jednostavno referenca funkcije, a ne poziv funkcije.

Funkcija onClick() je sada nešto poput omotača za doSomething() . Pomoću funkcija strelica možete napraviti "omote" ovog tipa:

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

Kao alternativu, mogli bismo koristiti i .bind() , koji ne zahtijeva nikakve omote (funkcije strelica ili bilo šta drugo):

Const User = React.createClass(function() ( render: function() (vrati nekog korisnika) ))

Podrška pretraživača za funkcije strelica

Ako vam je potrebna podrška preglednika osim najnovije verzije Chrome I Firefox, koristiti Babel transpiler da konvertujete ES6 kod koji ste napisali u ES5.

ES6 ima novi način kreiranja funkcija - korištenjem operatora Strelica =>. Takve funkcije se nazivaju funkcije strelice. Nude kompaktniju sintaksu. Oni nemaju ime i drugačije rade sa ovim.

Prva stvar koju ćemo uraditi je pokrenuti Babel skriptu koja će pratiti datoteke i kreirati nove verzije kada se promijene.

Otvorite fasciklu projekta u komandna linija(KS). Unesite naredbu:

I pritisnite Enter

U folderu src kreiraćemo datoteku arr.js i odmah je naznačiti u datoteci index.html

</script>

Najnovije verzije pretraživača podržavaju funkcije strelica bez transpilacije i moj pretraživač je jedan od njih.

Napišimo funkciju koja sabira dva broja i vraća njihov zbir. Pozovimo funkciju add.

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

Na konzoli ćemo vidjeti rezultat - 9

Sada, hajde da pretvorimo ovu funkciju u funkciju strelice.

Uklonimo riječ funkcija, uklonimo naziv funkcije i uklonimo vitičaste zagrade, te riječ - return. Nakon parametara stavićemo strelicu.

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

Ako pogledate tip varijable add koristeći typeof operator:

Console.log(typeof(add));

To je ono što ćemo vidjeti u funkcijskoj konzoli

To znači da su funkcije strelice obične funkcije. A to možete provjeriti gledajući transpilirani kod.

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

Vidimo da je Babel pretvorio naš kod u jednostavan izraz funkcije.

Napišimo jednostavnu funkciju koja će kvadrirati dati broj.

Neka add = (x, y) => x + y; console.log(add(4, 6)); console.log(typeof(add)); neka kvadrat = funkcija(a) (vrati a * a; ) console.log(kvadrat (4));

Pogledajmo u konzoli:

Funkcija strelice će izgledati ovako:

Neka je kvadrat = x => x * x;

Ako funkcija sa strelicom uzima samo jedan parametar, nema potrebe da je stavljate u zagrade!

Napišimo funkciju koja uopće ne uzima parametre.

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

Ova funkcija jednostavno ispisuje na konzolu broj 33. Strelica:

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

Kreirajmo funkciju koja neće ništa vratiti. Jednostavno će prikazati poruku u konzoli pretraživača.

Neka log = function () ( console.log("Hello World!"); ); log();

Prekidač:

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

Kreirajmo funkciju čije će se tijelo sastojati od dvije linije.

Funkcija će uzeti dva parametra. Kreirajmo varijablu u tijelu funkcije. Nakon toga ćemo vratiti rezultat.

Neka mult = funkcija (a, b) ( neka rezultat = a * b; vrati rezultat; ) console.log(mult (4, 5));

Ako u funkciji strelice postoji nekoliko linija, tada su potrebne vitičaste zagrade - ()! I obavezno definirajte šta ova funkcija vraća koristeći ključnu riječ return

Prekidač:

Neka mult = (a, b) => ( neka rezultat = a * b; vrati rezultat; ) console.log(mult (4, 5));

Sada kreirajmo funkciju koja vraća literal objekta:

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

U konzoli ćemo vidjeti:

Pokušajmo sada kreirati funkciju strelice koja će vratiti literal objekta.

Treba imati na umu da ako funkcija strelice vraća literal objekta, tada su potrebne zagrade - ()

Funkcija strelice koja vraća literal objekta:

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

Pokušajmo sada upotrijebiti funkciju strelice kao IIFE - izraz funkcije koja se odmah poziva

Ukratko, ovo je funkcija koja se izvršava odmah nakon deklaracije

izgleda ovako:

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

Funkcija strelice IIFE će izgledati ovako:

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

Važna karakteristika funkcija strelica je da strelica mora doći odmah nakon parametara!

Ne možete ga jednostavno uzeti i pomjeriti dolje na red ispod. To će dati grešku!

Praktična primjena funkcija strelica. Funkcije strelica su vrlo zgodne za korištenje s nizovima.

Kreirajmo niz sa nekim brojevima i nazovimo ga brojevima. Mislim da znate da nizovi imaju korisne metode koje vam omogućavaju iteraciju kroz niz, filtriranje, itd.

Izračunajmo zbir svih varijabli niza. Da bih to uradio, deklarisaću drugu varijablu - neka sum = 0;

Koristimo metodu forEach() koju ima svaki niz, mi ćemo iterirati preko elemenata i dodati zbroju.

Neka brojevi = ; neka suma = 0; numbers.forEach(funkcija(broj) (zbir += broj; )); console.log(suma);

U konzoli ćemo vidjeti 55. Pretvorimo ovu funkciju u funkciju strelice: numbers.forEach(num => sum += num); console.log(suma);

Dakle, ono što nam je ranije uzimalo tri reda, sada uzima jedan.

Također možemo kvadrirati svaki element niza.

Neka je na kvadrat = brojevi.mapa(n => n * n); console.log(kvadrat);

Funkcije sa strelicama i ovo. Da bih to uradio, kreiraću objektni literal koji ću sačuvati u promenljivoj person.

Objekt person će imati svojstvo imena sa vrijednošću 'Bob' i svojstvo greet sa vrijednošću 'Greet'. Ispisat ćemo pozdrav na konzolu i također pogledati svrhu ovog .

Pusti osobu = ( ime: "Bob", greet: function () ( console.log("Zdravo! Moje ime je " + ovo.name); console.log(ovo); ) ); person.greet();

U konzoli pretraživača videćemo pozdrav i sam objekat osobe.

Sada ćemo funkciju zamijeniti strelicom i vidjeti što će se dogoditi s ovim.

Pusti osobu = ( ime: "Bob", pozdravi: () => ( console.log("Zdravo! Moje ime je " + ovo.name); console.log(ovo); ) ); person.greet();

Sada nismo dobili vrijednost imena i vrijednost ovoga je window !

Ali zašto? Poenta je da je vrijednost ovoga uzeta iz konteksta u kojem je funkcija deklarirana. ! Bez obzira gdje će se ova funkcija obavljati. Ovo se vidi na slici:

Imamo program.

Za sada u njemu nema ničega osim objekta prozora. Dodan objekt osobe. Primijetite da za metodu koristimo funkciju strelice. Kao što smo rekli, vrijednost ovoga će se uzeti iz konteksta. Kontekst je okruženje. U ovom slučaju će biti okruženje objekta osobe, sva njegova svojstva i metode prozorski objekat. A ako se vrijednost ovoga uzme iz konteksta, onda će se to odnositi na objekt prozora.

Ako pogledamo regularnu funkciju, onda znamo da se to odnosi na sam objekt osobe. Možete pitati zašto je vrijednost ovoga u funkcijama strelica uzeta iz konteksta? A odgovor je vrlo jednostavan - oni su to uradili na taj način! :-) Poenta je da su funkcije strelice stvorene za rješavanje problema u drugačijoj situaciji. Pogledajmo primjer. Da vidimo problem vratit ćemo se na našu funkciju strelice.

Pusti osobu = ( ime: "Bob", greet: function () ( console.log("Zdravo! Moje ime je " + ovo.name); console.log(ovo); ) );

Zamislimo da je naš Bob prilično zauzet i da mu treba nekoliko sekundi da završi posao. Sačekajte 2 sekunde. simuliramo pomoću funkcije setTimeout(); .Ova funkcija uzima funkciju kao prvi parametar i broj milisekundi za čekanje kao drugi parametar.

Neka osoba = ( ime: "Bob", greet: function () ( setTimeout(function () ( console.log("Zdravo! Moje ime je " + ovo.name); console.log(this); ), 2000) ; ) ); person.greet();

Ako imate iskustva sa JavaScript-om, mislim da razumijete u čemu je problem. U svakom slučaju, pogledajmo šta će se dogoditi u pretraživaču. Tačno dvije sekunde kasnije videćemo ovu sliku u pretraživaču.

Ali zašto? Ako pogledate naš kod, logično je pretpostaviti. da se ovo odnosi na objekat osobe pošto koristimo regularnu funkciju. Stvar je u tome što setTimeout() pripada prozorskom objektu. Ako to napišete ovako: window.setTimeout() , onda mislite na šta se to odnosi? I u konzoli ćemo dobiti isti rezultat! Postoji nekoliko načina za rješavanje ovog problema u ES5. Pogledaćemo onu najčešću: prije setTimeout(), deklariraću drugu varijablu koja će joj dodijeliti vrijednost. A sada, u tijelu funkcije, umjesto ovoga, naznačićemo to.

Neka osoba = ( ime: "Bob", pozdrav: funkcija () ( neka to = ovo; setTimeout(function () ( console.log("Zdravo! Moje ime je " + to.name); console.log(that)) ; ), 2000); ) ); person.greet();

Sada, zahvaljujući zatvaranju, funkcija koju šaljemo setTimeout() imat će pristup varijabli that, čija će vrijednost biti this, odnosno, u ovom slučaju, objekt person.

Radi jasnoće, možete pogledati na šta se odnosi naše ono i ovo.

Neka osoba = ( ime: "Bob", greet: funkcija () ( neka to = ovo; setTimeout(function () ( console.log("Zdravo! Moje ime je " + that.name); console.log("It je moje To = " + to); console.log("To je moje Ovo = " + ovo); ), 2000); ) ); person.greet();

Vidjet ćemo potvrdu u konzoli:

Vidimo da će ovo biti objekt prozora - This = , a to će biti naš objekt person - That = .

U ES6 možemo jednostavno koristiti funkciju strelice da riješimo ovaj problem.

Pusti osobu = ( ime: "Bob", greet: function () ( setTimeout(() => ( console.log("Zdravo! Moje ime je " + this.name); console.log("To je moje Ovo = " + ovo); ), 2000.); ) ); person.greet();

Kao rezultat, vidjet ćemo na konzoli:

IN grafički primjer za funkciju strelice, kontekst će biti objekt osobe, a ne prozorski objekat. zato će se ovo odnositi na osobu .

Pored kompaktne sintakse, uvedene su funkcije strelica za rješavanje problema poput ovih.

Za referencu, možete vidjeti kako je Babel ovo riješio

Var person = ( ime: "Bob", greet: funkcija greet() ( var _this = this; setTimeout(function () ( console.log("Zdravo! Moje ime je " + _this.name); console.log(" To je moje Ovo = " + _this); ), 2000); ) ); person.greet(); Babel je koristio istu metodu koju smo koristili u ES5. Jedina razlika je u tome što smo promenljivu nazvali tako, a Babel je nazvao - _ovo. Zahvaljujući zatvaranju, funkcija koju šaljemo u setTimeout imat će pristup varijabli _this i, kao rezultat, objektu person.

Mislim da je najteži dio ovog dijela razumjeti kako funkcionišu zatvaranja.

Još neke karakteristike funkcija strelica:
Više informacija o ES6 i funkcijama strelica možete vidjeti u mom postu

Zdravo svima! U ovom članku ćemo pogledati koje su funkcije strelice u ES6 i kako ih koristiti.

Funkcije strelice su funkcije koje su napisane pomoću operatora strelice (=>).

Pogledajmo odmah primjer:

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

Kao rezultat izvršavanja ove funkcije, vidjet ćemo broj 7 u konzoli.

Prvo prosljeđujemo argumente u zagradama, zatim stavljamo znak strelice, a zatim pišemo kod same funkcije. U našem slučaju, jednostavno uzima dva broja i sabira ih. U teoriji, ovo je isto kao izraz funkcije u ES5. Ako koristite Babel ili slične kompajlere, oni će najvjerovatnije napisati nešto poput ovoga:

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

Ako vaša funkcija uzima samo jedan parametar, zagrade nisu obavezne.

Neka je kvadrat = x => x*x;

Ova funkcija uzima samo jedan argument i kvadrira dati broj.

Funkcija bez parametara:

Neka func = () => 77;

Ako vaša funkcija sadrži nekoliko redaka, onda, prvo, trebate koristiti vitičaste zagrade, a drugo, obavezno napišite šta funkcija vraća, tj. koristite ključnu riječ return.

Neka se pomnoži = (x, y) => (
neka rezultat = x*y;
vratiti rezultat;
};

Ako trebate vratiti literal objekta, onda ga morate umotati u zagrade:

Neka getObject = () => (( marka: "BMW" ));

Funkcija samopozivanja izgleda ovako:

Izraz funkcije strelice je sintaktički kompaktna alternativa izrazu regularne funkcije, iako bez vlastitih veza za ključne riječi this, arguments, super ili new.target. Izrazi funkcije strelice nisu prikladni kao metode i ne mogu se koristiti kao konstruktori.

Sintaksa Osnovna sintaksa (param1, param2, …, paramN) => ( izrazi ) (param1, param2, …, paramN) => izraz // ekvivalentno: => ( povratni izraz; ) // Zagrade su opcione kada postoje samo jedno ime parametra: (singleParam) => ( iskazi ) singleParam => ( iskazi ) // Lista parametara za funkciju bez parametara treba biti napisana sa parom zagrada. () => ( iskazi ) Napredna sintaksa // Stavite u zagrade tijelo funkcije da biste vratili literalni izraz objekta: params => ((foo: bar)) // Parametri odmora i zadani parametri su podržani (param1, param2, ...rest) => ( izrazi) (param1 = defaultValue1, param2, …, paramN = defaultValueN) => ( iskazi) // Destrukturiranje unutar liste parametara je također podržano var f = ( = , (x: c) = (x: a + b)) => a + b + c; f(); // 6 Opis

Dva faktora su uticala na uvođenje funkcija sa strelicama: potreba za kraćim funkcijama i ponašanje ove ključne reči.

Kraće funkcije var elements = [ "Vodik", "Helijum", "Litijum", "Berilijum" ]; // Ova izjava vraća niz: elements.map (function(element) ( return element.length; )); // Gornja regularna funkcija može se napisati kao funkcija strelice ispod elements.map((element) => ( return element.length; )); // // Kada postoji samo jedan parametar, možemo ukloniti okolne zagrade elements.map (element => ( return element.length; )); // // Kada je jedini izraz u funkciji strelice `return`, možemo ukloniti `return` i ukloniti // okolne vitičaste zagrade elements.map(element => element.length); // // U ovom slučaju, budući da nam je potrebno samo svojstvo dužine, možemo koristiti parametar destrukturiranja: // Primijetite da `length` odgovara svojstvu koje želimo dobiti, dok je // očigledno nespecijalna `lengthFooBArX` samo ime varijable koje se može promijeniti // u bilo koje važeće ime varijable koje želite elements.map ((( length:lengthFooBArX )) => lengthFooBArX); // // Ova dodjela parametara destrukturiranja također se može napisati kao što se vidi ispod. Međutim, imajte na umu da u // ovom primjeru ne dodjeljujemo vrijednost `dužine` napravljenom svojstvu. Umjesto toga, samo literalno ime // varijable `length` koristi se kao svojstvo koje želimo dohvatiti iz objekta. elements.map ((( dužina )) => dužina); // Nema odvojenog ovo

Prije funkcija sa strelicama, svaka nova funkcija definirala je svoju ovu vrijednost na osnovu načina na koji je funkcija pozvana:

  • Novi objekat u slučaju konstruktora.
  • undefined u strogom modu poziva funkcije.
  • Osnovni objekt ako je funkcija pozvana kao "metoda objekta".

Ovo se pokazalo manje nego idealno sa objektno orijentisanim stilom programiranja.

Funkcija Person() ( // Konstruktor Person() definira `this` kao instancu samog sebe. this.age = 0; setInterval(function growUp() ( // U nestriktnom načinu rada, growUp() funkcija definira ` this` // kao globalni objekat (jer se tu izvodi growUp().), // koji se razlikuje od `this` // definiranog od strane Person() konstruktora. this.age++; ), 1000) ; ) var p = nova osoba();

U ECMAScript-u 3/5, ovaj problem se mogao popraviti dodjeljivanjem vrijednosti u ovom promjenljivoj koja se može zatvoriti.

Funkcija Person() ( var that = this; that.age = 0; setInterval(function growUp() ( // Povratni poziv se odnosi na varijablu `that` čija je // vrijednost očekivani objekt. that.age++; ) , 1000); ) "koristi strogo"; var obj = (a: 10); Object.defineProperty(obj, "b", ( get: () => ( console.log(this.a, typeof this.a, this); // undefined "undefined" Window (...) (ili globalni object) return this.a + 10; // predstavlja globalni objekat "Window", stoga "this.a" vraća "undefined" ) ));

Upotreba novog operatera

Funkcije sa strelicama ne mogu se koristiti kao konstruktori i ispostavit će grešku kada se koriste s novim .

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

Upotreba svojstva prototipa

Funkcije strelice nemaju svojstvo prototipa.

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

Upotreba ključne riječi yield

Ključna riječ yield se ne smije koristiti u tijelu funkcije strelice (osim kada je to dozvoljeno unutar funkcija koje su dalje ugniježđene u njoj). Kao posljedica toga, funkcije strelice se ne mogu koristiti kao generatori.

Tijelo funkcije

Funkcije sa strelicama mogu imati ili "sažeto tijelo" ili uobičajeno "telo bloka".

U sažetom tijelu, samo je izraz specificiran, koji postaje implicitna povratna vrijednost. U tijelu bloka morate koristiti eksplicitnu povratnu naredbu.

Var func = x => x * x; // sažeta sintaksa tijela, implicirano "povratak" var func = (x, y) => ( return x + y; ); // sa tijelom bloka, potreban je eksplicitni "povratak".

Vraćanje literala objekata

Imajte na umu da vraćanje literala objekata koristeći sažetu sintaksu tijela params => (object:literal) neće raditi kako se očekuje.

Var func = () => ( foo: 1 ); // Pozivanje funkcije func() vraća nedefinirano! var func = () => ( foo: function() () ); // SyntaxError: izraz funkcije zahtijeva ime

To je zato što se kod unutar zagrada (()) raščlanjuje kao niz naredbi (tj. foo se tretira kao oznaka, a ne ključ u literalu objekta).

Morate umotati literal objekta u zagrade:

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

Prelomi linija

Funkcija strelice ne može sadržavati prijelom reda između svojih parametara i svoje strelice.

Var func = (a, b, c) => 1; // SyntaxError: očekivani izraz, dobio "=>"

Međutim, ovo se može izmijeniti stavljanjem prijeloma reda nakon strelice ili korištenjem zagrada/zagrada kao što se vidi ispod kako bi se osiguralo da kod ostane lijep i pahuljast. Također možete staviti prijelome reda između argumenata.

Var func = (a, b, c) => 1; var func = (a, b, c) => (1); var func = (a, b, c) => (vraćanje 1); var func = (a, b, c) => 1; // nema SyntaxError bačena

Redoslijed raščlanjivanja

Iako strelica u funkciji strelice nije operator, funkcije strelice imaju posebna pravila raščlanjivanja koja različito djeluju s prioritetom operatora u odnosu na regularne funkcije.

Neka povratni poziv; povratni poziv = povratni poziv || funkcija(); // ok povratni poziv = povratni poziv || () => (); // SyntaxError: nevažeći argumenti funkcije strelice povratni poziv = povratni poziv || (() => ()); // uredu

Više primjera // Prazna funkcija strelice vraća undefined let empty = () => (); (() => "foobar")(); // Vraća "foobar" // (ovo je izraz funkcije koji se odmah poziva) var simple = a => a > 15 ? 15: a; jednostavno(16); // 15 jednostavno(10); // 10 neka max = (a, b) => a > b ? a: b; // Jednostavno filtriranje niza, mapiranje, ... 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); // // Sažetiji lanci obećanja obećanje.then(a => ( // ... )).then(b => ( // ... )); // Funkcije strelice bez parametara koje je vizualno lakše raščlaniti setTimeout(() => ( console.log("Ja se dogodi prije"); setTimeout(() => ( // dublji kod console.log("Ja se dogodi kasnije") ; ), jedanaest); Specifikacije Komentar statusa specifikacije
ECMAScript 2015 (6. izdanje, ECMA-262)
Standard Početna definicija.
ECMAScript najnoviji nacrt (ECMA-262)
Definicija "Definicije funkcije strelice" u toj specifikaciji.
Nacrt
Kompatibilnost pretraživača

Tabela kompatibilnosti na ovoj stranici je generirana iz strukturiranih podataka. Ako želite doprinijeti podacima, pogledajte https://github.com/mdn/browser-compat-data i pošaljite nam zahtjev za povlačenje.

Ažurirajte podatke o kompatibilnosti na GitHub-u

Desktop Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Android web pregled Chrome za Android Firefox za Android Opera za Android Safari na iOS-u Samsung Internet Node.jsFunkcije sa strelicama Zadnji zarez u parametrima
Chrome puna podrška 45Edge Potpuna podrška DaFirefox Puna podrška 22

Bilješke

Potpuna podrška 22

Bilješke

Bilješke Prije Firefoxa 39, terminator linije (\n) je bio pogrešno dozvoljen nakon argumenata funkcije strelice. Ovo je ispravljeno da bi bilo u skladu sa ES2015 specifikacijom i kodom kao što je () \n =>
IE Nema podrške brOpera Puna podrška 32Safari puna podrška 10WebView Android Puna podrška 45Chrome Android Puna podrška 45Firefox Android Puna podrška 22

Bilješke

Potpuna podrška 22

Bilješke

Bilješke Početna implementacija funkcija strelica u Firefoxu ih je učinila automatski strogim. Ovo je promijenjeno od Firefoxa 24. Upotreba "strogo upotrebe"; je sada potrebno. Bilješke Prije Firefoxa 39, terminator linije (\n) je bio pogrešno dozvoljen nakon argumenata funkcije strelice. Ovo je ispravljeno da bi bilo u skladu sa ES2015 specifikacijom i kod kao što je () \n => () će sada izbaciti SyntaxError u ovoj i kasnijim verzijama.
Opera Android Puna podrška 32Safari iOS Puna podrška 10Samsung Internet Android Puna podrška 5.0nodejs Potpuna podrška Da
Chrome puna podrška 58Edge?Firefox Puna podrška 52IE Nema podrške brOpera Puna podrška 45Safari?WebView Android Puna podrška 58Chrome Android Puna podrška 58Firefox Android Puna podrška 52Opera Android Puna podrška 43Safari iOS?Samsung Internet Android Puna podrška 7.0nodejs Potpuna podrška Da
Legenda Potpuna podrška Potpuna podrška Nema podrške Nema podrške Kompatibilnost nepoznata Kompatibilnost nepoznata Pogledajte napomene o implementaciji. Pogledajte napomene o implementaciji.
  • Tutorial

Jedan od najzanimljivijih dijelova novog standarda ECMAScript 6 su funkcije strelica. Funkcije strelica, kao što ime sugerira, definirane su novom sintaksom koja koristi strelicu => . Međutim, pored odlične sintakse, funkcije strelica se razlikuju od tradicionalnih funkcija na druge načine:

  • Leksičko uvezivanje. Vrijednosti posebne varijable this, super i argumenti nisu određeni načinom na koji su pozvane funkcije strelice, već načinom na koji su kreirane.
  • Nepromenljivo ovo, super i argumenti. Vrijednosti ovih varijabli unutar funkcija strelica ostaju nepromijenjene životni ciklus funkcije.
  • Funkcije strelice se ne mogu koristiti kao konstruktor i ispuštaju grešku kada se koriste s operatorom new.
  • Nedostupnost “nativne” vrijednosti varijable argumenata.
Bilo je nekoliko razloga za uvođenje ovih razlika. Prvi je da se vezivanje često koristi u JavaScript-u. Vrlo je lako izgubiti ispravnu ovu vrijednost kada koristite tradicionalne funkcije, što može dovesti do neočekivanih posljedica. Drugi razlog je taj što će JS motori moći lako optimizirati izvršavanje funkcija strelica zbog ovih ograničenja (za razliku od tradicionalnih funkcija koje se mogu koristiti kao konstruktor i koje su slobodne za modifikaciju posebne varijable).


Napomena: Ovaj članak je kompilacija iz besplatnog prijevoda članka Razumijevanje funkcija strelice ECMAScript 6 i čitanje najnovijeg nacrta specifikacije (20. januara 2014. Nacrt Rev 22).

Sintaksa Općenito, sintaksa funkcija sa strelicama izgleda ovako:

Var fun = (x) => x;
Vrlo je slična sličnoj sintaksi u jezicima kao što su Scala, CoffeeScript i sintaksi lambda izraza iz C#.

Sintaksa funkcija sa strelicama može varirati ovisno o tome kako deklarišete funkciju. Deklaracija uvijek počinje listom argumenata, praćenom strelicom i tijelom funkcije. I lista argumenata i tijelo funkcije mogu imati različite oblike, ovisno o tome što pišete.

Jedan parametar Deklariranje funkcije strelice koja uzima jedan argument i jednostavno ga vraća vrlo je jednostavno:

Varreflekt = vrijednost => vrijednost; // ekvivalentno varreflektu = funkcija(vrijednost) (povratna vrijednost;)
Kada funkcija strelice ima samo jedan argument, može se deklarirati bez zagrada. Tijelo funkcije koje slijedi nakon strelice također možda nema vitičaste zagrade i možda ne sadrži ključnu riječ return.

Više parametara Ali ako želite deklarirati više od jednog parametra, morate priložiti listu parametara u zagrade:

Var suma = (num1, num2) => num1 + num2; // ekvivalentno var sum = function(num1, num2) (vraćanje num1 + num2; );
Funkcija suma jednostavno dodaje dva argumenta. Jedina razlika u odnosu na prethodni primjer je prisustvo zagrada i zareza (baš kao u tradicionalnim funkcijama).

Bez parametara Slično, funkcija bez ikakvih argumenata mora imati praznu listu parametara zatvorenu u zagrade:

Var zbroj = () => 1 + 2; // ekvivalentno var sum = function() (vraćanje 1 + 2; );

Tradicionalna sintaksa tijela funkcije Možete koristiti tradicionalnu sintaksu funkcije za tijelo funkcije strelice kada sadrži više od jednog izraza. To jest, umotajte funkciju u vitičaste zagrade i dodajte ključnu riječ return:

Var sum = (num1, num2) => ( return num1 + num2; ) // ekvivalentno var sum = function(num1, num2) ( return num1 + num2; );
Tijelo funkcije će biti obrađeno na potpuno isti način kao i za klasične funkcije, osim vrijednosti posebne varijable ovo , super i argumenti će biti različito ocijenjeni.

Objektni literal Odvojeno, treba napomenuti da tijelo funkcije koje ne sadrži vitičaste zagrade i jednostavno vraća literal objekta treba biti zatvoreno u zagradama:

Var getTempItem = id => (( id: id, ime: "Temp" )); // ekvivalentno var getTempItem = function(id) ( return ( id: id, name: "Temp" ));
Postavljanje literala objekta u zagrade govori parseru da vitičaste zagrade nisu početak tradicionalne sintakse za tijelo funkcije, već početak literala.

Varijabilni broj parametara Budući da “nativni” argumenti objekat nije dostupan unutar funkcije strelice (vrijednost argumenata je leksički povezana s vrijednošću argumenata tradicionalne funkcije unutar koje je deklarirana funkcija strelice), onda za funkcije strelice sa varijabilni broj parametara iz kojih trebate koristiti uzorak odmora destrukturiranje obrazaca. primjer:

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

Predložak destrukturiranja kao parametar Za potrebe ovog članka, ne razmatramo obrasce destrukturiranja – o njima možete pročitati u članku Pregled ECMAScript 6, sljedeće verzije JavaScripta, iako su ove informacije djelimično zastarjele.

Kao što možete vidjeti iz prethodnog primjera, iako funkcija strelice ima samo jedan argument, i dalje morate koristiti zagrade kada koristite destrukturiranje obrazaca kao jedini parametar funkcije. Primjeri sa drugima šabloni:

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

Korišćenje funkcija strelice Postavljanje konteksta Jedan uobičajeni scenario u JavaScript-u je postavljanje ispravne ove vrednosti unutar funkcije (vezivanje). Budući da se vrijednost ovoga može mijenjati, ovisno o kontekstu u kojem se funkcija izvršava, moguće je pogrešno djelovati na jedan objekt kada ste mislili na nešto sasvim drugo. Pogledajte sljedeći primjer:

Var pageHandler = ( id: "123456" , init: function() (document.addEventListener("click", function(event) ( this.doSomething(event.type); // greška )); ) , doSomething: function( type) ( console.log("Rukovanje " + tip + " za " + this.id) ) );
U gornjem kodu, pageHandler objekat bi trebao upravljati klikovima na stranici. Metoda init() vezuje rukovalac za željeni događaj, koji interno poziva this.doSomething() . Međutim, kod neće raditi ispravno. Referenca na this.doSomething() nije važeća jer ukazuje na objekt dokumenta unutar rukovaoca događaja umjesto na predviđeni pageHandler. Ako pokušate pokrenuti ovaj kod, dobit ćete grešku jer objekt dokumenta nema metodu doSomething.

Možete povezati ovu vrijednost sa objektom pageHandler koristeći handleEvent ili pozivom standardne metode bind() u funkciji:

Var pageHandler = ( id: "123456" , init: function() (document.addEventListener("klik", (funkcija(događaj) (ovo.doSomething(event.type); // greška)).bind(ovo)) ; ) , doSomething: function(type) ( console.log("Rukovanje " + tip + " za " + this.id) ) );
Sada kod radi kako je predviđeno, ali izgleda glomaznije. Osim toga, pozivanjem bind(this) svaki put kada kreirate novu funkciju čija je ova vrijednost vezana za vrijednost pageHandler, ali kod radi kako ste namjeravali.

Funkcije strelice rješavaju problem na elegantniji način jer koriste leksičko vezivanje za vrijednost this (kao i super i argumente ) i njegova vrijednost je određena vrijednošću this na lokaciji gdje je funkcija strelice kreirana. Na primjer:

Var pageHandler = ( id: "123456" , init: function() (document.addEventListener("click", event => this.doSomething(event.type)); ) , doSomething: function(type) ( console.log( "Rukovanje " + tip + " za " + this.id) ) );
U ovom primjeru, rukovatelj je funkcija strelice koja poziva this.doSomething() . Vrijednost ovoga bit će ista kao u funkciji init() i kodu u u ovom primjeruće raditi ispravno, slično onom koji je koristio bind() . Bez obzira na to da li poziv this.doSomething() vraća vrijednost ili ne, izraz unutar tijela funkcije strelice ne mora biti zatvoren u vitičastim zagradama.

Osim toga, gornji primjer je također efikasniji od pozivanja bind() jer je isti kao sljedeći kod za pretraživač:

Var pageHandler = ( id: "123456" , init: function() ( var self = this; document.addEventListener("click", function(event) (vraćanje self.doSomething(event.type) )); ) , doSomething: function(type) ( console.log("Rukovanje " + tip + " za " + this.id) ) );
To jest, stvaranje se ne dešava nova funkcija, kao što je slučaj sa pozivom bind().

“Bacanje” konteksta između nekoliko poziva Očigledno, možete ugnijezditi jednu funkciju strelice u drugu, na taj način “bacivši” vrijednost this kroz njih:

Var obj = ( arr1: , arr2: ["a", "b", "c"], spojiti: function(a, b)( return a + "|" + b) , presjek: function() (vrati ovo .arr1.reduce((sum, v1) => // funkcija strelice 1 this.arr2.reduce((sum, v2) => ( // funkcija strelice 2 sum.push(this.concatenate(v1, v2)) return zbroj; ) , zbir) , ) ) ); var arrSum = obj.intersection();//["1|a", "1|b", "1|c", "2|a", "2|b", "2|c", "3 |a", "3|b", "3|c"]

Upotreba kao argument Kratka sintaksa funkcija sa strelicama čini ih idealnim kandidatima za prosljeđivanje kao argumenata u druge pozive funkcija. Na primjer, ako želite sortirati niz, obično biste napisali nešto poput ovoga:

Var rezultat = values.sort(funkcija(a, b) (vrat a - b));
Prilično opširno za jednostavnu operaciju. Uporedite sa kratkom notacijom za funkciju strelice:

Var rezultat = values.sort((a, b) => a - b);
Upotreba metoda kao što su array() , map() , reduce() i tako dalje može se pojednostaviti korištenjem sintakse funkcije kratke strelice.

Ostale karakteristike funkcija strelica Iako se funkcije strelice razlikuju od tradicionalnih funkcija, one imaju neke zajedničke karakteristike:
  • Operator typeof će vratiti "function" za funkciju strelice
  • Funkcija strelice je također instanca funkcije "class", tako da će instanceof raditi isto kao i s tradicionalnom funkcijom
  • I dalje možete koristiti metode call() , apply() i bind(), ali zapamtite da one neće utjecati na vrijednost ovog
  • Možete koristiti metodu toMethod(), međutim ona neće promijeniti vrijednost super ( metoda toMethod() uvedena je u es6 i nije pokrivena u ovom članku).
Značajna razlika od tradicionalnih funkcija je u tome što će pokušaj pozivanja funkcije sa strelicom pomoću novog operatora uzrokovati grešku u izvođenju Rezime Funkcije strelice su jedna od najzanimljivijih inovacija u ECMAScript 6, koja će, imajući sažetu sintaksu definicije, pojednostaviti prosljeđivanje funkcija kao vrijednosti parametra drugoj funkciji.

Sažeta sintaksa će vam omogućiti da složene stvari pišete još složenije na jednostavniji način. Na primjer, ovako će izgledati generator identifikatora (koji izgleda mnogo opširnije na es5):

Neka idGen = (start = 0, id = početak, reset = (noviId = početak) => id = noviId, sljedeći = () => id++) => ((reset, sljedeći)); neka gen = idGen(100); console.log(gen.next(), gen.next(), gen.reset(10), gen.next());//100 101 10 10
A leksičko povezivanje će zatvoriti jedan od najvećih izvora bola i frustracije za programere, a takođe će poboljšati performanse zbog optimizacije na nivou js engine-a.


Ako želite isprobati funkcije sa strelicama, možete pokrenuti gornje primjere u Firefox konzoli, koja je uključena ovog trenutka(02.2014 FF28) gotovo u potpunosti podržava funkcije strelice (FF28 pogrešno izračunava vrijednost argumenata).

Također možete isprobati funkcije strelice i druge funkcije es6 u online prevodiocu Traceur.

Oznake: Dodaj oznake