Internet Windows Android

Funcții săgeți. ES6

12 răspunsuri

Ce este asta

Aceasta este funcția săgeată. Funcțiile săgeată sunt o scurtă sintaxă introdusă în ECMAscript 6 care poate fi utilizată într-un mod similar cu modul în care ați folosi expresiile de funcție. Cu alte cuvinte, le puteți folosi adesea în loc de expresii precum funcția (foo) (...) . Dar au câteva diferențe importante. De exemplu, ei nu își leagă propriile valori (vezi discuția de mai jos).

Funcțiile Arrow fac parte din specificația ECMAscript 6. Ele nu sunt încă acceptate în toate browserele, dar sunt parțial sau complet acceptate în Node v. 4.0+ și în majoritatea browserelor moderne utilizate începând cu 2018. (Mai jos este o listă parțială a browserelor acceptate).

Din documentația Mozilla:

O expresie a funcției de săgeată (cunoscută și sub numele de funcție de săgeată grasă) are o sintaxă mai scurtă decât expresiile de funcție și leagă lexical valoarea this (nu își leagă propriile this , arguments , super sau new.target ). Funcțiile săgeților sunt întotdeauna anonime. Aceste expresii de funcție sunt cele mai potrivite pentru funcții non-metode și nu pot fi utilizate ca constructori.

O notă despre cum funcționează acest lucru în funcțiile săgeților

Una dintre cele mai convenabile caracteristici ale funcției săgeată este ascunsă în textul de mai sus:

Funcția săgeată... leagă lexical valoarea acestui (nu își leagă propriul this...)

În termeni simpli, aceasta înseamnă că funcția săgeată stochează valoarea this din contextul său și nu are propriul this . O funcție tradițională poate lega această valoare singură, în funcție de modul în care este definită și numită. Acest lucru poate necesita multă gimnastică, cum ar fi self = this; etc. pentru a accesa sau manipula aceasta dintr-o funcție în interiorul altei funcții. Pentru mai multe informații despre acest subiect, consultați explicația și exemplele din documentația Mozilla.

Exemplu de cod

Exemplu (tot din documente):

Var a = [ „Suntem trează toată noaptea „până la soare”, „Suntem trează toată noaptea să luăm niște”, „Suntem trează toată noaptea pentru a ne distra”, „Suntem trează toată noaptea pentru a obține lucky" ]; // Aceste două sarcini sunt echivalente: // Old-school: var a2 = a.map(function(s)( return s.length )); // ECMAscript 6 folosind funcțiile săgeată var a3 = a.map (s => s.length // atât a2 cât și a3 vor fi egale cu).

Note de compatibilitate

Puteți utiliza funcțiile de săgeți în Node, dar suportul pentru browser nu este în întregime corect.

Suportul de browser pentru această funcționalitate s-a îmbunătățit semnificativ, dar încă nu este suficient de răspândit pentru majoritatea aplicațiilor bazate pe browser. Începând cu 12 decembrie 2017, este acceptat în versiunile actuale:

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

Nu este acceptat în:

  • IE (înainte de art. 11)
  • Opera Mini (până la versiunea 8.0)
  • Browser Blackberry (până la versiunea 10)
  • IE Mobile (până la versiunea 11)
  • UC Browser pentru Android (până la versiunea 11.4)
  • QQ (până la versiunea 1.2)

Puteți găsi mai multe (și mai actuale) informații la CanIUse.com (fără afiliere).

Aceasta este cunoscută sub numele de funcție săgeată, parte a specificației ECMAScript 2015...

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

Sintaxă mai scurtă decât anterioară:

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

Un alt lucru uimitor este lexical asta... De obicei, faci ceva de genul:

function Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( var self = this; setInterval(function() ( // acesta este Window, nu Foo (), așa cum te-ai putea aștepta console.log(this // // de aceea reatribum acest lucru la self înainte de setInterval() console.log(self.count++); ) nou Foo();

Dar acest lucru poate fi rescris folosind o săgeată ca aceasta:

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

Aceasta ar fi „expresia funcției săgeată” introdusă în ECMAScript 6.

În scopuri istorice (dacă pagina wiki se modifică mai târziu), acesta este:

O expresie de funcție săgeată are o sintaxă mai scurtă decât o expresie de funcție și leagă lexical acea valoare. Funcțiile săgeților sunt întotdeauna anonime.

Cunoscute și sub denumirea de funcții Fat Arrow. Acesta este un mod simplu și clar de a scrie expresii de funcție, cum ar fi function() () .

Funcțiile săgeată pot elimina nevoia de funcții , returnare și () atunci când definiți funcții. Sunt o linie similară cu expresiile lambda din Java sau Python.

Exemplu fără parametri

const queue = ["Dave", "Sarah", "Sharon"]; const nextCustomer = () => coada; console.log(nextCustomer()); // „Dave”

Dacă trebuie să faceți mai multe instrucțiuni în aceeași funcție săgeată, acest exemplu vă cere să includeți coada între acolade () . În acest caz, declarația de returnare nu poate fi omisă.

Exemplu cu 1 parametru

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

Puteți omite () din cele de mai sus.

Când există un singur parametru, parantezele () din jurul parametrului pot fi omise.

Exemplu cu parametri multipli

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

Exemplu util const fructe = [ (nume: „Mer”, preț: 2), (nume: „Banana”, preț: 3), (nume: „Pere”, preț: 1) ];

Dacă am dori să obținem prețul fiecărui fruct într-o singură matrice, în ES5 am putea face:

Fructe.hartă(funcție(fruct) ( return fructe.preț; )); //

În ES6, cu noile funcții de săgeată, putem face acest lucru mai concis:

Fructe.harta(fructe => fructe.pret); //

Mai multe informații despre funcțiile săgeților pot fi găsite.

Compatibilitate browser
  • IE: nu este încă acceptat
  • Edge: 12+ (Toate versiunile)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • iOS Safari: 10.2+
  • Browser Android: 56+

Pentru mai multe informații actualizate despre compatibilitatea browserului, vă rugăm să vizitați

După cum au spus alții, aceasta este o nouă sintaxă pentru crearea de funcții.

Cu toate acestea, acest tip de funcție este diferit de cele obișnuite:

    Ele leagă valoarea acestui . După cum explică specificația,

    ArrowFunction nu definește legături locale pentru argumente , super , this sau new.target . Orice referire la argumente , super , this , sau new.target în cadrul unei ArrowFunction rezolvă legarea în mediul lexical. De obicei, acesta va fi un mediu funcțional imediat o funcție.

    Chiar dacă ArrowFunction poate conține referințe la super, obiectul funcție creat la pasul 4 nu este transformat într-o metodă prin executarea MakeMethod. O funcție ArrowFunction care face referire la super este întotdeauna conținută într-o funcție non-săgeată, iar implementarea necesară a super este accesibilă prin domeniul care este capturat de obiectul funcției ArrowFunction.

  • Sunt non-constructori.

    Aceasta înseamnă că nu au o metodă [] internă și, prin urmare, nu pot fi instanțiate, de exemplu

    Var f = a => a; f(123); // 123 f(); // TypeError: f nu este un constructor

Adăugarea unui exemplu CRUD simplu cu o săgeată

//Funcția săgeată var clienți = [ ( nume: „Dave”, contact: „9192631770” ), ( nume: „Sarah”, contact: „9192631770” ), ( nume: „Akhil”, contact: „9928462656” )] , // Fără parametri READ getFirstCustomer = () => ( console.log(this); return customers; ); console.log("Primul client"+JSON.stringify(getFirstCustomer())); // „Dave” //1 Param SEARCH getNthCustomer = index=>( if(index>customers.length) ( return „Nu așa ceva”; ) else( return customers; ) ); console.log("Al-lea client este " +JSON.stringify(getNthCustomer(1))); //2params ADD addCustomer = (nume, contact) => customers.push(( "nume": nume, "contact":contact )); addCustomer("Hitesh","8888813275"); console.log ("Client adăugat "+JSON.stringify(clienți)); //2 param UPDATE updateCustomerName = (index, newName)=>(customers.name= newName); updateCustomerName(customers.length-1,"HiteshSahu"); console.log("Client actualizat"+JSON.stringify(clienți)); //1 param DELETE removeCustomer = (clientToRemove) => customers.pop(customerToRemove); removeCustomer(getFirstCustomer()); console.log("Client eliminat "+JSON.stringify(clienți));

La fel ca toate celelalte răspunsuri, aceasta face parte din sintaxa funcției ES2015. Mai exact, nu este un operator, este un token token care separă parametrii de corp: ArrowFunction: ArrowParameters => ConciseBody . De exemplu. (params) => ( /* body */ ) .

În javascript, simbolul => este un simbol de expresie a funcției săgeată. O expresie a funcției săgeată nu are această legare proprie și, prin urmare, nu poate fi utilizată ca funcție de constructor. De exemplu:

var cuvinte = „salut din exterior obiect”; let obj = ( cuvinte: "bună din interiorul obiectului", talk1: () => (console.log(this.words)), talk2: function () (console.log(this.words)) ) obj.talk1( ); // nu are propriul this binding, this === window obj.talk2() // are propria this binding, this is obj

Reguli pentru utilizarea funcțiilor săgeată:
  • Dacă există un singur argument, puteți omite parantezele argumentului.
  • Dacă returnați o expresie și o faceți pe aceeași linie, puteți omite instrucțiunea () și return

De exemplu:

fie times2 = val => val * 2; // Este pe aceeași linie și returnează o expresie prin urmare () sunt comite și expresia returnează implicit // există și un singur argument, prin urmare parantezele din jurul argumentului sunt omise console.log(times2(3));

Nemulțumit de alte răspunsuri. Cel mai votat răspuns pe 2019/3/13 este incorect din punct de vedere faptic.

O versiune scurtă și succintă a ceea ce înseamnă => este o comandă rapidă pentru a scrie o funcție și pentru a o asocia cu curentul this

Const foo = a => a * 2;

Efectiv scurtătură pentru

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

Puteți vedea toate lucrurile care au fost tăiate. Nu avem nevoie de function , return , .bind(this) , paranteze sau paranteze

Un exemplu puțin mai lung de funcție săgeată ar putea fi

Const foo = (lățime, înălțime) => ( const area = lățime * înălțime; zona de întoarcere; );

Arată că, dacă avem nevoie de mai multe argumente ale funcției, avem nevoie de paranteze, iar dacă dorim să scriem mai multe expresii, avem nevoie de acolade și de o returnare explicită.

Este important să înțelegeți partea .bind și este un subiect mare. Acest lucru are de-a face cu ceea ce înseamnă asta în JavaScript.

TOATE funcțiile au un parametru implicit numit acesta. Modul în care este setat atunci când se apelează o funcție depinde de modul în care este apelată funcția.

Accept

Funcția foo() ( console.log(this); )

Daca il spui ok

Funcția foo() ( console.log(this); ) foo();

acesta va fi un obiect global.

Dacă ești în modul strict

„utilizați strict”; funcția foo() ( console.log(this); ) foo(); // sau funcția foo() ( „utilizați strict”; console.log(this); ) foo();

Va fi nedefinit

Puteți seta acest lucru direct folosind apel sau aplicați

Funcția foo(msg) ( console.log(msg, this); ) const obj1 = (abc: 123) const obj2 = (def: 456) foo.call(obj1, "hello"); // afișează Hello (abc: 123) foo.apply(obj2, ["hi"]); // afișează Salut (definiție: 456)

Puteți seta acest lucru implicit folosind operatorul punct.

Funcția foo(msg) ( console.log(msg, this); ) const obj = ( abc: 123, bar: foo, ) obj.bar("Hola"); // imprimă Hola (abc:123, bar: f)

Problema apare atunci când doriți să utilizați o funcție ca apel invers sau ascultător. Creați o clasă și doriți să atribuiți o funcție ca apel invers care accesează o instanță a clasei.

Clasa ShowName ( constructor (nume, elem) ( this.name = nume; elem.addEventListener ("clic", function() ( console.log(this.name); // nu va funcționa )); ) )

Codul de mai sus nu va funcționa deoarece atunci când elementul generează evenimentul și apelează funcția, această valoare nu va fi o instanță a clasei.

O modalitate obișnuită de a rezolva această problemă este utilizarea .bind

Clasa ShowName ( constructor(nume, elem) ( this.name = nume; elem.addEventListener("click", function() ( console.log(this.name); ).bind(this); // ( console.log (acest nume); )); ) )

bind realizează în mod eficient o nouă funcție. Dacă bind nu ar exista, ai putea să-ți faci singur așa

Funcția bind(funcitonToBind, valueToUseForThis) (funcția return(...args) ( functionToBind.call(valueToUseForThis, ...args); )

În JavaScript vechi, fără operatorul de răspândire, aceasta ar fi

Funcția bind(funcitonToBind, valueToUseForThis) ( return function() ( functionToBind.apply(valueToUseForThis, argumente); )

Înțelegerea faptului că codul necesită înțelegerea închiderilor, dar versiunea scurtă a bind creează o nouă funcție care apelează întotdeauna funcția originală cu această valoare legată de aceasta. Funcția săgeată face același lucru, deoarece sunt o comandă rapidă pentru a lega (acest lucru)

Săgeata funcție, care este reprezentată de simbolul (=>), vă ajută să creați funcții și metode anonime. Acest lucru are ca rezultat o sintaxă mai scurtă. De exemplu, mai jos este o funcție simplă Adaugă care returnează adunarea a două numere.

Funcția Add(num1 , num2)( return num1 + num2; )

Funcția de mai sus devine mai scurtă folosind sintaxa Arrow, așa cum se arată mai jos.

Codul de mai sus este format din două părți, așa cum se arată în imaginea de mai sus:

Intrare: - Această secțiune specifică parametrii de intrare pentru funcția anonimă.

Logica: - Această secțiune vine după simbolul „=>”. Această secțiune are logica funcției reale.

Mulți dezvoltatori cred că funcția săgeată vă face sintaxa mai scurtă, mai simplă și, prin urmare, vă face codul ușor de citit.

Dacă credeți propoziția de mai sus, atunci permiteți-mi să vă asigur că este un mit. Dacă vă gândiți o clipă, o funcție scrisă corect cu un nume este mult mai lizibilă decât funcțiile criptice create pe o singură linie folosind un simbol săgeată.

Utilizarea principală a funcției săgeată este de a se asigura că codul este executat în contextul apelanților.

Vezi codul de mai jos care definește o variabilă globală „context”, această variabilă globală este accesibilă în interiorul funcției „SomeOtherMethod” care este apelată dintr-o altă metodă „SomeMethod”.

Această SomeMethod are o variabilă de context local. Acum, deoarece SomeOtherMethod este apelat de la „SomeMethod”, ne așteptăm să afișeze „contextul local”, dar afișează „contextul global”.

Var context = „context global”; function SomeOtherMethod())( alert(this.context); ) function SomeMethod())( this.context = "context local"; SomeOtherMethod(); ) var instance = new SomeMethod();

Dar dacă înlocuiți apelul cu o funcție săgeată, aceasta va afișa „contextul local”.

Var context = „context global”; function SomeMethod())( this.context = "context local"; SomeOtherMethod = () => ( alert(this.context); ) SomeOtherMethod(); ) var instance = new SomeMethod();

Vă sfătuiesc să citiți acest link (Funcția săgeată în JavaScript) care explică toate scenariile de context javascript și în ce cazuri contextul apelantului nu este respectat.

Puteți vedea și demonstrația Săgeata funcționează cu javascript în acest videoclip YouTube, ceea ce demonstrează practic termenul de Context.

Despre cuvântul cheie JavaScript „acest”: caracteristici de utilizare cu explicații

Misterul acestui lucru

Multă vreme, acest cuvânt cheie a rămas un mister pentru mine. Este un instrument puternic, dar nu este ușor de înțeles.

Din punctul de vedere al Java, PHP sau al oricărui alt limbaj obișnuit, acesta este privit ca instanța obiectului curent în metoda clasei, nimic mai mult și nimic mai puțin. Cel mai adesea nu poate fi folosit în afara unei metode, iar această abordare nu este înțeleasă greșit.

În JavaScript, acesta este contextul de execuție curent al funcției. Deoarece o funcție poate fi apelată în patru moduri:

  • apel de funcție: alert(„Bună ziua, lume!”),
  • apel de metodă: console.log ("Bună ziua, lume!"),
  • apel constructor: new RegExp("\\d"),
  • apel indirect: alert.call(nedefinit, „Bună lume!”) ,

și fiecare dintre ele își definește propriul context, comportamentul acestuia este ușor inconsecvent cu ceea ce s-ar aștepta dezvoltatorii începători. În plus, modul strict afectează și contextul de execuție.

Cheia pentru înțelegerea acestui cuvânt cheie este să înțelegeți cum este numită o funcție și cum afectează contextul. Acest articol acoperă apelurile de funcții, modul în care apelurile afectează acest lucru și capcanele comune la identificarea contextului.

Înainte de a începe, să ne familiarizăm cu câțiva termeni:

  • Un apel este execuția codului corpului funcției. De exemplu, un apel la funcția parseInt ar fi parseInt("15") .
  • Contextul de apelare este această valoare din corpul funcției.
  • Domeniul de aplicare al unei funcții este setul de variabile, obiecte și funcții care pot fi accesate din corpul funcției.

  • 2.1.
    2.2.
    2.3.

  • 3.1.
    3.2.

  • 4.1.
    4.2.

  • 5.1.
  • CU
    6.1.

  • 7.1.
    7.2.
  • Apelarea unei funcții

    Un apel de funcție este efectuat atunci când expresia care este obiectul funcției este urmată de o paranteză deschisă (, o listă de argumente separate prin virgulă și o paranteză de închidere), de exemplu, parseInt("18") . O expresie nu poate fi un accesor la myObject.myFunction care efectuează un apel de metodă. De exemplu, .join(",") nu este un apel de funcție, ci un apel de metodă.

    Un exemplu simplu de apel de funcție:

    Funcția hello(nume) ( return "Hello " + nume + "!"; ) // Invocarea funcției var mesaj = hello("Lumea"); console.log(mesaj); // => "Bună lume!"

    hello("World") este un apel de funcție: hello este tratat ca un obiect funcție urmat de un argument "World" între paranteze.

    Mesajul Var = (funcție(nume) ( returnează „Bună ziua „ + nume + „!”; ))(„Lumea”); console.log(mesaj); // => "Bună lume!"

    Acesta este, de asemenea, un apel de funcție: prima pereche de paranteze (funcție(nume) (...)) este tratată ca un obiect funcție, urmată de un argument în paranteze: ("Lumea") .

    asta la apelarea unei funcții

    acesta este obiectul global la apelarea funcției

    Obiectul global este definit de mediul de rulare. Într-un browser web, acesta este obiectul fereastră.

    Într-un apel de funcție, contextul de execuție este obiectul global. Să verificăm contextul următoarei funcții:

    Funcția sum(a, b) ( console.log(this === fereastra); // => true this.myNumber = 20; // adăugați proprietatea „myNumber” la obiectul global return a + b; ) // sum( ) este invocată ca funcție // aceasta în sum() este un obiect global (fereastră) console.log(sum(15, 16)); // => 31 console.log(window.myNumber); // => 20

    Când sum(15, 16) este apelată, JavaScript inițializează automat acest lucru ca obiect global, care este fereastra din browser.

    Când aceasta este utilizată în afara domeniului de aplicare al oricărei funcții (sfera cea mai exterioară: contextul de execuție global), se referă și la obiectul global:

    Console.log(aceasta === fereastra); // => true this.myString = "Bună lume!"; console.log(window.myString); // => "Bună lume!" console.log(aceasta === fereastra); // => adevărat

    asta la apelarea unei funcții în modul strict

    aceasta este nedefinită atunci când se apelează o funcție în modul strict

    /* jshint esnext: true */ class City ( constructor(nume, călătorit) ( this.name = nume; this.traveled = false; ) travel() ( this.traveled = true; ) ) // Invocarea constructorului var paris = New City(„Paris”, false); paris.travel();

    new City(„Paris”) este un apel de constructor. Inițializarea obiectului este controlată de o metodă specială de clasă: constructor , al cărui obiect este nou creat.

    Apelarea unui constructor creează un nou obiect gol care moștenește proprietățile din prototipul constructorului. Rolul funcției de constructor este de a inițializa obiectul. După cum știți deja, contextul acestui tip de apel se numește instanță. Acesta este subiectul capitolului următor.

    Când accesorul myObject.myFunction este precedat de noul cuvânt cheie, JavaScript va efectua un apel de constructor mai degrabă decât un apel de metodă. Să luăm ca exemplu new myObject.myFunction(): mai întâi, folosind accesorul extractedFunction = myObject.myFunction, funcția este extrasă și apoi apelată ca constructor pentru a crea un nou obiect: new extractedFunction() .

    asta în apelul constructorului

    acesta este obiectul nou creat

    Contextul apelului constructorului este obiectul nou creat. Este folosit pentru a inițializa un obiect cu date din argumentul funcției constructor.

    Să verificăm contextul în exemplul următor:

    Funcția Foo () ( console.log(this instance of Foo); // => true this.property = "Valoare implicită"; ) // Invocarea constructorului var fooInstance = new Foo(); console.log(fooInstance.property); // => „Valoare implicită”

    new Foo() face un apel de constructor cu contextul fooInstance . Obiectul este inițializat în Foo: this.property este setat la o valoare implicită.

    Același lucru se întâmplă atunci când se folosește class, doar inițializarea are loc în metoda constructorului:

    /* jshint esnext: true */ class Bar ( constructor() ( console.log(this instance of Bar); // => true this.property = "Valoare implicită"; ) ) ) // Invocarea constructorului var barInstance = new Bar( ); console.log(barInstance.property); // => „Valoare implicită”

    Când noua Bar() este executată, JavaScript creează un obiect gol și îl transformă în contextul metodei constructorului. Acum puteți adăuga proprietăți folosind: this.property = "Valoare implicită" .

    Capcană: cum să nu uiți de nou

    Unele funcții JavaScript creează instanțe atunci când sunt apelate nu numai ca constructor, ci și ca funcție. De exemplu, RegExp:

    Var reg1 = new RegExp("\\w+"); var reg2 = RegExp("\\w+"); console.log(instanță reg1 de RegExp); // => adevărat console.log(instanța reg2 a RegExp); // => adevărat console.log(reg1.source === reg2.source); // => adevărat

    Când sunt executate noi RegExp("\\w+") și RegExp("\\w+"), JavaScript creează obiecte de expresie regulată echivalente.

    Utilizarea unui apel de funcție pentru a crea un obiect este potențial periculoasă (dacă omiteți metoda din fabrică), deoarece unii constructori pot să nu inițializeze obiectul în absența noului cuvânt cheie.

    Următorul exemplu ilustrează problema:

    Funcție Vehicle(type, wheelsCount) ( this.type = type; this.wheelsCount = wheelsCount; return this; ) // Invocarea funcției var car = Vehicle("Mașină", ​​4); console.log(car.type); // => „Mașină” console.log(car.wheelsCount); // => 4 console.log(masina === fereastra); // => adevărat

    Vehicul este o funcție care setează proprietățile tip și wheelsCount ale obiectului context. Când se execută Vehicle(„Mașină”, 4), returnează un obiect mașină cu proprietățile corecte: car.type este egal cu „Mașină” și car.wheelsCount este 4 . Este ușor să crezi că totul funcționează așa cum trebuie.

    Totuși, acesta este obiectul fereastră atunci când funcția este apelată, iar Vehicul(„Mașină”, 4) setează proprietățile obiectului fereastră - hopa, ceva a mers prost. Noul obiect nu a fost creat.

    Asigurați-vă că utilizați noul operator atunci când este așteptat un apel de constructor:

    Funcție Vehicul(tip, număr roți) ( if (!(această instanță a vehiculului)) ( throw Error("Eroare: invocare incorectă"); ) this.type = type; this.wheelsCount = wheelsCount; return this; ) // Invocare constructor var mașină = vehicul nou ("Mașină", ​​4); console.log(car.type); // => „Mașină” console.log(car.wheelsCount); // => 4 console.log(instanță de mașină a vehiculului); // => adevărat // Invocarea funcției. Generează o eroare. var brokenCar = Vehicul(„Mașină spartă”, 3);

    Vehicul nou ("Mașină", ​​4) funcționează corect: un obiect nou este creat și inițializat deoarece cuvântul nou este prezent.

    Verificare adăugată la apelul funcției: această instanță a vehiculului pentru a se asigura că contextul de execuție are tipul de obiect corect. Dacă acesta nu este Vehicul , este generată o eroare. Astfel, dacă se execută Vehicle("Broken Car", 3) (fără nou), atunci se aruncă o excepție: Error: Incorrect invocation .

    Apel indirect

    Un apel indirect este efectuat atunci când o funcție este apelată prin metodele .call() sau .apply().

    /* jshint esnext: true */ var sumArguments = (...args) => ( console.log(typeof arguments); // => „nedefinit” return args.reduce((rezultat, item) => rezultat + element ); console.log(sumArguments.name); // => "" console.log(sumArguments(5, 5, 6)); // => 16

    aceasta într-o funcție săgeată

    acesta este contextul în care este definită funcția săgeată

    O funcție săgeată nu își creează propriul context de execuție, ci împrumută acest lucru din funcția externă în care este definită.

    Următorul exemplu arată transparența contextului:

    /* jshint esnext: true */ class Point ( constructor(x, y) ( this.x = x; this.y = y; ) log() ( console.log(this === myPoint); setTimeout(() => ( console.log(this === myPoint); // => true console.log(this.x + ":" + this.y); // => "95:165" ), 1000); ) ) var myPoint = new Point(95, 165); myPoint.log();

    setTimeout apelează funcția săgeată în același context (metoda myPoint) ca și metoda log(). După cum putem vedea, o funcție săgeată „moștenește” contextul funcției în care este definită.

    Dacă încercați să utilizați o funcție obișnuită în acest exemplu, aceasta își va crea propriul context (fereastră sau nedefinit). Prin urmare, pentru ca codul să funcționeze corect, trebuie să legați manual contextul: setTimeout(function() (...).bind(this)) . Acest lucru este greoi, deci este mai ușor să utilizați funcția săgeată.

    Dacă o funcție săgeată este definită în afara tuturor funcțiilor, contextul ei este un obiect global:

    /* jshint esnext: true */ var getContext = () => ( console.log(this === window); // => true return this; ); console.log(getContext() === fereastra); // => adevărat

    Funcția săgeată este asociată cu contextul lexical odată pentru totdeauna. aceasta nu poate fi schimbată nici măcar folosind metoda schimbării contextului:

    /* jshint esnext: true */ var numere = ; (function() (var get = () => ( return this; ); console.log(this === numere); // => true console.log(get()); // => // Utilizați funcția săgeată cu .apply() și .call() console.log(get.call()); // => console.log(get.apply() // => // Bind console.log(get ); .bind()()); // => )).call(numbers);

    O funcție numită indirect folosind .call(numbers) setează aceasta la valoarea numerelor. Funcția săgeată get primește, de asemenea, numere deoarece preia contextul lexical. Indiferent cum este numit get, contextul său va fi întotdeauna numere. Apelarea indirectă într-un context diferit (folosind .call() sau .apply()), relegarea (folosind .bind()) nu va avea niciun efect.

    Funcția săgeată nu poate fi folosită ca constructor. Dacă apelați new get() , JavaScript va arunca eroarea: TypeError: get not a constructor .

    Capcană: definirea unei metode cu o funcție săgeată

    Poate doriți să utilizați o funcție săgeată pentru a declara o metodă. Destul de corect: declarațiile lor sunt mult mai scurte în comparație cu expresia obișnuită: (param) => (...) în loc de function(param) (..) .

    Acest exemplu demonstrează definirea metodei format() a clasei Period folosind o funcție săgeată:

    /* jshint esnext: true */ function Period (ore, minute) ( this.hours = ore; this.minutes = minute; ) Period.prototype.format = () => ( console.log(this === fereastra) ; // =>

    Deoarece formatul este o funcție săgeată definită în context global, acesta este obiectul fereastră. Chiar dacă formatul este executat ca metodă a obiectului walkPeriod.format(), window rămâne contextul de apelare. Acest lucru se întâmplă deoarece funcția săgeată are un context static care nu este modificat de alte tipuri de apeluri.

    aceasta este fereastra, deci this.hours și this.minutes devin nedefinite. Metoda returnează șirul „ore nedefinite și minute nedefinite” care nu este rezultatul dorit.

    O expresie a funcției rezolvă problema deoarece o funcție obișnuită își schimbă contextul în funcție de apel:

    Funcție Perioada (ore, minute) ( this.hours = ore; this.minutes = minute; ) Period.prototype.format = function() ( console.log(this === walkPeriod); // => true return this. ore + „ore și „ + this.minutes + „minute” ); var walkPeriod = new Period(2, 30); console.log(walkPeriod.format());

    walkPeriod.format() este un apel de metodă cu contextul walkPeriod. this.hours ia valoarea 2 și this.minutes ia 30 , deci metoda returnează rezultatul corect: „2 ore și 30 de minute” .

    Concluzie

    Deoarece apelul funcției are cel mai mare impact asupra acestui lucru, de acum înainte, nu mai întrebați:

    De unde vine asta?

    si intreaba:

    Cum se numește funcția?

    Și în cazul unei funcții săgeată, întrebați:

    Ce este acesta unde este declarată funcția săgeată?

    Această abordare te va scuti de dureri de cap inutile.

    Nu vă confundați în contexte! 🙂

    O expresie de funcție săgeată este o alternativă compactă din punct de vedere sintactic la o expresie de funcție obișnuită , deși fără propriile legături la cuvintele cheie this , arguments , super sau new.target . Expresiile funcției săgeți nu sunt potrivite ca metode și nu pot fi folosite ca constructori.

    Sintaxă Sintaxă de bază (param1, param2, …, paramN) => ( instrucțiuni ) (param1, param2, …, paramN) => expresie // echivalentă cu: => ( expresie returnată; ) // Parantezele sunt opționale atunci când există un singur nume de parametru: (singleParam) => ( statements ) singleParam => ( statements ) // Lista de parametri pentru o funcție fără parametri trebuie scrisă cu o pereche de paranteze () => ( statements ) Sintaxă avansată // Parantezizare corpul unei funcții pentru a returna o expresie literală a obiectului: params => ((foo: bar)) // Parametrii Rest și parametrii impliciti sunt acceptați (param1, param2, ...rest) => ( instrucțiuni ) (param1 = defaultValue1 , param2, …, paramN = defaultValueN) => ( statements ) // Destructurarea în lista de parametri este acceptată și var f = ( = , (x: c) = (x: a + b)) => a + b + c; f();

    Doi factori au influențat introducerea funcțiilor săgeată: nevoia de funcții mai scurte și comportamentul cuvântului cheie this.

    Funcții mai scurte var elemente = [ "Hidrogen", "Heliu", "Litiu", "Beriliu" ]; // Această instrucțiune returnează tabloul: elements.map (funcție(element) ( return element.length; )); // Funcția obișnuită de mai sus poate fi scrisă ca funcție săgeată sub elements.map((element) => ( return element.length; )); // // Când există un singur parametru, putem elimina parantezele din jur elements.map (element => ( return element.length; )); // // Când singura instrucțiune dintr-o funcție săgeată este `return`, putem elimina `return` și eliminăm // ​​parentelele din jur elements.map(element => element.length); // // În acest caz, deoarece avem nevoie doar de proprietatea lungime, putem folosi parametrul de destructurare: // Observați că `length` corespunde proprietății pe care vrem să o obținem, în timp ce // evident nespecială `lengthFooBArX` este doar numele unei variabile care poate fi schimbată // la orice nume de variabilă valid pe care doriți elemente.map ((( length:lengthFooBArX )) => lengthFooBArX); // // Această atribuire a parametrilor de destructurare poate fi scrisă și așa cum se vede mai jos. Cu toate acestea, rețineți că în // acest exemplu nu atribuim valoare `length` proprietății create. În schimb, numele literal // însuși al variabilei `lungime` este folosit ca proprietate pe care dorim să o recuperăm de la obiect. elemente.hartă ((( lungime )) => lungime); // Nu separă asta

    Înainte de funcțiile săgeată, fiecare funcție nouă și-a definit propria această valoare pe baza modului în care a fost numită funcția:

    • Un obiect nou în cazul unui constructor.
    • nedefinit în apelurile de funcții în modul strict.
    • Obiectul de bază dacă funcția a fost numită ca „metodă obiect”.

    Acest lucru sa dovedit a fi mai puțin decât ideal cu un stil de programare orientat pe obiecte.

    Funcția Person() ( // Constructorul Person() definește `this` ca o instanță a lui însuși. this.age = 0; setInterval(function growUp() ( // În modul non-strict, funcția growUp() definește ` this` // ca obiect global (deoarece este locul unde growUp() este executat.), // care este diferit de `this` // definit de constructorul Person(). this.age++; ), 1000) ; ) var p = new Person();

    În ECMAScript 3/5, această problemă a fost rezolvabilă prin atribuirea valorii din aceasta unei variabile care ar putea fi închisă.

    Funcție Person() ( var that = this; that.age = 0; setInterval(function growUp() ( // Callback-ul se referă la variabila `that`) a cărei // valoarea este obiectul așteptat. that.age++; ) , 1000); „utilizare strict”; var obj = (a: 10); Object.defineProperty(obj, "b", ( get: () => ( console.log(this.a, typeof this.a, this); // undefined "undefined" Fereastra (...) (sau global obiect) returnează this.a + 10 // reprezintă obiectul global „Fereastră”, prin urmare „this.a” returnează „nedefinit” ) ));

    Utilizarea noului operator

    Funcțiile săgeată nu pot fi folosite ca constructori și vor genera o eroare atunci când sunt utilizate cu new .

    Var Foo = () => (); var foo = new Foo(); // TypeError: Foo nu este un constructor

    Utilizarea proprietății prototipului

    Funcțiile săgeată nu au o proprietate prototip.

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

    Utilizarea cuvântului cheie yield

    Cuvântul cheie yield nu poate fi folosit în corpul unei funcții săgeată (cu excepția cazului în care este permis în cadrul funcțiilor imbricate mai departe în ea). În consecință, funcțiile săgeată nu pot fi utilizate ca generatoare.

    Corpul funcției

    Funcțiile săgeată pot avea fie un „corp concis”, fie „corp de bloc” obișnuit.

    Într-un corp concis, este specificată doar o expresie, care devine valoarea implicită returnată. Într-un corp de bloc, trebuie să utilizați o instrucțiune de returnare explicită.

    Var func = x => x * x; // sintaxă corporală concisă, implicit „return” var func = (x, y) => ( return x + y; ); // cu corpul blocului, este necesar „întoarcerea” explicită

    Literele obiect returnate

    Țineți minte că returnarea literalelor obiectului folosind parametrii conciși de sintaxă a corpului => (object:literal) nu va funcționa așa cum vă așteptați.

    Var func = () => ( foo: 1 ); // Apelarea func() returnează nedefinit! var func = () => ( foo: function() () ); // SyntaxError: instrucțiunea funcției necesită un nume

    Acest lucru se datorează faptului că codul din acolade (()) este analizat ca o secvență de instrucțiuni (adică foo este tratat ca o etichetă, nu o cheie într-un obiect literal).

    Trebuie să împachetați literalul obiect în paranteze:

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

    Rupere de linie

    O funcție săgeată nu poate conține o întrerupere de linie între parametrii săi și săgeata.

    Var func = (a, b, c) => 1; // SyntaxError: expresie așteptată, a primit „=>”

    Cu toate acestea, acest lucru poate fi modificat prin introducerea rupturii de linie după săgeată sau folosind paranteze/acolade, așa cum se vede mai jos, pentru a vă asigura că codul rămâne frumos și pufos. De asemenea, puteți pune întreruperi de linie între argumente.

    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; // nu a fost aruncată nicio Eroare de Sintaxă

    Ordinea de analiză

    Deși săgeata dintr-o funcție săgeată nu este un operator, funcțiile săgeată au reguli speciale de analiză care interacționează diferit cu precedența operatorului în comparație cu funcțiile obișnuite.

    Permite apel invers; callback = apel invers || funcţie(); // ok callback = apel invers || () => (); // SyntaxError: argumente nevalide ale funcției săgeată callback = callback || (() => ()); // Bine

    Mai multe exemple // O funcție săgeată goală returnează undefined let empty = () => (); (() => "foobar")(); // Returnează „foobar” // (aceasta este o expresie a funcției invocate imediat) var simple = a => a > 15 ? 15: a; simplu(16); // 15 simplu(10); // 10 fie max = (a, b) => a > b ? a: b; // Filtrare simplă a matricei, mapare, ... var arr = ; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // var dublu = arr.map(v => v * 2); // // Lanțuri de promisiuni mai concise promise.then(a => ( // ... )).then(b => ( // ... )); // Funcții de săgeți fără parametri, care sunt vizual mai ușor de analizat setTimeout(() => ( console.log("M-am întâmplat mai devreme"); setTimeout(() => ( // cod mai profund console.log("M-am întâmplat mai târziu") ; ), unsprezece); Specificații Comentariu privind starea specificațiilor
    ECMAScript 2015 (ediția a 6-a, ECMA-262)
    Standard Definiție inițială.
    Ultima versiune ECMAScript (ECMA-262)
    Definiția „Arrow Function Definitions” din specificația respectivă.
    Proiect
    Compatibilitate browser

    Tabelul de compatibilitate de pe această pagină este generat din date structurate. Dacă doriți să contribuiți la date, vă rugăm să consultați https://github.com/mdn/browser-compat-data și să ne trimiteți o cerere de extragere.

    Actualizați datele de compatibilitate pe GitHub

    Desktop Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Vizualizare web Android Chrome pentru Android Firefox pentru Android Opera pentru Android Safari pe iOS Samsung Internet Node.jsFuncții săgeți Virgulă finală în parametri
    Suport complet Chrome 45Edge Suport complet DaFirefox Suport complet 22

    Note

    Suport total 22

    Note

    Note Înainte de Firefox 39, un terminator de linie (\n) era permis incorect după argumentele funcției săgeată. Acest lucru a fost remediat pentru a se conforma specificației ES2015 și codului precum () \n =>
    IE Fără suport NrOpera Suport complet 32Safari Suport complet 10WebView Android Suport complet 45Chrome Android Suport complet 45Firefox Android Suport complet 22

    Note

    Suport total 22

    Note

    Note Implementarea inițială a funcțiilor săgeată în Firefox le-a făcut automat stricte. Acest lucru a fost modificat începând cu Firefox 24. Utilizarea „use strict”; acum este necesar. Note Înainte de Firefox 39, un terminator de linie (\n) era permis incorect după argumentele funcției săgeată. Acest lucru a fost remediat pentru a se conforma cu specificația ES2015 și codul precum () \n => () va arunca acum o SyntaxError în această versiune și în versiunile ulterioare.
    Opera Android Suport complet 32Safari iOS Suport complet 10Samsung Internet Android Suport complet 5.0nodejs Suport complet Da
    Suport complet Chrome 58Margine?Firefox Suport complet 52IE Fără suport NrOpera Suport complet 45Safari?WebView Android Suport complet 58Chrome Android Suport complet 58Firefox Android Suport complet 52Opera Android Suport complet 43Safari iOS?Samsung Internet Android Suport complet 7.0nodejs Suport complet Da
    Legendă Suport complet Suport complet Fără suport Nici un suport Compatibilitate necunoscută Compatibilitate necunoscută Vezi notele de implementare. Vezi notele de implementare.

    Salutare tuturor! În acest articol, ne vom uita la ce funcții de săgeți sunt în ES6 și cum să le folosim.

    Funcțiile săgeată sunt funcții care sunt scrise folosind operatorul săgeată (=>).

    Să ne uităm imediat la un exemplu:

    Fie adăugare = (x, y) => x + y;
    console.log(add(5, 2));

    Ca urmare a executării acestei funcții, vom vedea numărul 7 în consolă.

    Mai întâi, trecem argumentele în paranteze, apoi punem semnul săgeată și apoi scriem codul funcției în sine. În cazul nostru, pur și simplu ia două numere și le adună. În teorie, aceasta este aceeași cu expresia funcției în ES5. Dacă utilizați Babel sau compilatoare similare, cel mai probabil vor scrie ceva de genul acesta:

    Var add = funcția add(x, y) (
    returnează x + y;
    };

    Dacă funcția dumneavoastră ia doar un parametru, parantezele sunt opționale.

    Fie pătrat = x => x*x;

    Această funcție ia doar un argument și pătratează numărul dat.

    Funcție fără parametri:

    Fie func = () => 77;

    Dacă funcția dvs. conține mai multe linii, atunci, în primul rând, trebuie să utilizați acolade și, în al doilea rând, asigurați-vă că scrieți ce returnează funcția, adică. utilizați cuvântul cheie return.

    Să se înmulțească = (x, y) => (
    fie rezultatul = x*y;
    returnează rezultatul;
    };

    Dacă trebuie să returnați un obiect literal, atunci trebuie să îl înfășurați în paranteze:

    Let getObject = () => (( marca: "BMW" ));

    Funcția de auto-invocare arată astfel:

    ES6 are o nouă modalitate de a crea funcții - Folosind operatorul Arrow =>. Astfel de funcții sunt numite funcții săgeți. Ele oferă o sintaxă mai compactă. Nu au un nume și lucrează diferit cu asta.

    Primul lucru pe care îl vom face este să rulăm un script Babel care va monitoriza fișierele și va crea versiuni noi atunci când se schimbă.

    Să deschidem folderul de proiect în linia de comandă (CS). Introdu comanda:

    Și apăsați Enter

    În folderul src vom crea un fișier arr.js și îl vom indica imediat în fișierul index.html

    </script>

    Cele mai recente versiuni de browsere acceptă funcții de săgeți fără transpilare, iar browserul meu este unul dintre ele.

    Să scriem o funcție care adună două numere și returnează suma lor. Să numim funcția add .

    Funcția add (x, y) ( return x + y; ) console.log (add (3, 6));

    În consolă vom vedea rezultatul - 9

    Acum, să convertim această funcție într-o funcție săgeată.

    Să eliminăm cuvântul function , să eliminăm numele funcției și să eliminăm acoladele și cuvântul - return . După parametri vom pune o săgeată.

    Fie adăugare = (x, y) => x + y; console.log(add(4, 6));

    Dacă vă uitați la tipul variabilei de adăugare folosind operatorul typeof:

    Console.log(tip de (adăugare));

    Aceasta este ceea ce vom vedea în consola de funcții

    Aceasta înseamnă că funcțiile săgeată sunt funcții obișnuite. Și puteți verifica acest lucru uitându-vă la codul transpilat.

    „utilizați strict”; var _typeof = tip de Simbol === „funcție” && tip de Simbol.iterator === „simbol” ? function (obj) ( return typeof obj; ) : function (obj) ( return obj && typeof Symbol === „funcție” && obj.constructor === Simbol && obj !== Symbol.prototype ? „simbol” : tip de obj ; var add = function add(x, y) ( return x + y; ); console.log(add(4, 6)); console.log(tip de adăugare === „nedefinit” ? „nedefinit” : _tip de (adăugare));

    Putem vedea că Babel a transformat codul nostru într-o expresie de funcție simplă.

    Să scriem o funcție simplă care va pătra un număr dat.

    Fie adăugare = (x, y) => x + y; console.log(add(4, 6)); console.log(tip de (adăugare)); fie pătrat = function(a) ( return a * a; ) console.log(pătrat (4));

    Să ne uităm în consolă:

    Funcția săgeată va arăta astfel:

    Fie pătrat = x => x * x;

    Dacă o funcție săgeată ia doar un parametru, atunci nu este nevoie să o închideți în paranteze!

    Să scriem o funcție care nu ia deloc parametri.

    Funcția givNumer () ( return 33; ) console.log(givNumer ());

    Această funcție imprimă pur și simplu numărul 33 pe săgeată:

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

    Să creăm o funcție care nu va returna nimic. Pur și simplu va afișa un mesaj în consola browserului.

    Let log = function () ( console.log("Bună lume!"); ); Buturuga();

    Intrerupator:

    Let log = () => console.log("Bună lume!!!"); Buturuga();

    Să creăm o funcție al cărei corp va fi format din două linii.

    Funcția va lua doi parametri. Să creăm o variabilă în corpul funcției. După aceea vom returna rezultatul.

    Fie mult = function (a, b) ( fie rezultat = a * b; return result; ) console.log(mult (4, 5));

    Dacă există mai multe linii într-o funcție de săgeată, atunci sunt necesare bretele - ()! Și asigurați-vă că definiți ce returnează această funcție folosind cuvântul cheie return

    Intrerupator:

    Fie mult = (a, b) => ( fie rezultat = a * b; returnează rezultat; ) console.log(mult (4, 5));

    Acum să creăm o funcție care returnează un obiect literal:

    Fie literal = function () ( return (nume: "Ioan"); ) console.log (literal ());

    În consolă vom vedea:

    Acum să încercăm să creăm o funcție săgeată care va returna un obiect literal.

    Trebuie amintit că, dacă o funcție săgeată returnează un obiect literal, atunci sunt necesare paranteze - ()

    Funcția săgeată care returnează un obiect literal:

    Fie literal = () => ((nume: „Ioan”); console.log(literal());

    Acum să încercăm să folosim funcția săgeată ca IIFE - expresie funcție invocată imediat

    Pe scurt, aceasta este o funcție care este executată imediat după declarație

    Arata cam asa:

    (funcția () ( console.log("IIFE"); ))();

    Funcția săgeată IIFE va arăta astfel:

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

    O caracteristică importantă a funcțiilor săgeții este că săgeata trebuie să vină imediat după parametri!

    Nu puteți să o luați și să o mutați în jos pe o linie de mai jos. Va da o eroare!

    Aplicarea practică a funcțiilor săgeților. Funcțiile săgeată sunt foarte convenabile de utilizat cu matrice.

    Să creăm o matrice cu câteva numere și să o numim numere. Cred că știi că matricele au metode utile care îți permit să iterați prin matrice, să o filtrați etc.

    Să calculăm suma tuturor variabilelor matricei. Pentru a face acest lucru, voi declara o altă variabilă - fie suma = 0;

    Să folosim metoda forEach() pe care o are fiecare tablou, vom repeta peste elemente și vom adăuga la sumă.

    Fie numere = ; fie suma = 0; numere.pentruFiecare(funcție(num) ( suma += num; )); console.log(sumă);

    În consolă vom vedea 55. Să transformăm această funcție într-o funcție săgeată: numere.forEach(num => sum += num); console.log(sumă);

    Astfel, ceea ce înainte ne lua trei rânduri, acum ia una.

    De asemenea, putem pătra fiecare element al matricei.

    Fie pătrat = numere.hartă(n => n * n); console.log(pătrat);

    Funcțiile săgeată și asta. Pentru a face acest lucru, voi crea un obiect literal pe care îl voi salva în variabila persoană.

    Obiectul persoană va avea o proprietate name cu valoarea „Bob” și o proprietate greet cu valoarea „Salut”. Vom imprima salutul pe consolă și vom analiza, de asemenea, scopul.

    Lăsați persoană = (nume: „Bob”, salut: funcție () ( console.log(„Bună ziua! Numele meu este „ + this.name); console.log(this); ) ); persoana.saluta();

    În consola browserului vom vedea salutul și obiectul persoană în sine.

    Acum vom înlocui funcția cu o săgeată și vom vedea ce se întâmplă cu aceasta.

    Persoanele = ( nume: „Bob”, salut: () => ( console.log(„Bună ziua! Numele meu este „ + this.name); console.log(this); ) ); persoana.saluta();

    Acum nu am primit valoarea numelui și valoarea acestuia este fereastră!

    Dar de ce? Ideea este că valoarea acestuia este luată din contextul în care este declarată funcția. ! Indiferent unde va fi îndeplinită această funcție. Asta se vede in poza:

    Avem un program.

    Până acum nu există nimic în el, cu excepția obiectului fereastră. S-a adăugat un obiect persoană. Observați că folosim o funcție săgeată pentru metodă. După cum am spus, valoarea acestui lucru va fi luată din context. Contextul este mediul. În acest caz, mediul obiectului persoană, toate proprietățile și metodele sale, vor fi obiectul fereastră. Și dacă valoarea acestuia este luată din context, atunci aceasta se va referi la obiectul fereastră.

    Dacă ne uităm la o funcție obișnuită, atunci știm că aceasta se referă la obiectul persoană în sine. Vă puteți întreba de ce valoarea acestui lucru în funcțiile săgeată este luată din context? Și răspunsul este foarte simplu - așa au procedat! :-) Ideea este că funcțiile săgeată au fost create pentru a rezolva probleme într-o situație diferită. Să ne uităm la un exemplu. Pentru a vedea problema, vom reveni la funcția săgeată.

    Lăsați persoană = (nume: „Bob”, salut: funcție () ( console.log(„Bună ziua! Numele meu este „ + this.name); console.log(this); ) );

    Să ne imaginăm că Bob al nostru este destul de ocupat și are nevoie de câteva secunde pentru a-și finaliza munca. Așteptați 2 secunde. simulăm folosind funcția setTimeout(); .Această funcție ia o funcție ca prim parametru și numărul de milisecunde de așteptat ca al doilea parametru.

    Persoanele = (nume: "Bob", salut: function () ( setTimeout(function () ( console.log ("Bună ziua! Numele meu este " + this.name); console.log(this); ), 2000) ; ) ); persoana.saluta();

    Dacă aveți experiență cu JavaScript, atunci cred că înțelegeți care este problema. Oricum, să ne uităm la ce se va întâmpla în browser. Exact două secunde mai târziu vom vedea această imagine în browser.

    Dar de ce? Dacă te uiți la codul nostru, este logic să presupunem. că aceasta se referă la obiectul persoană, deoarece folosim o funcție obișnuită. Chestia este că setTimeout() aparține obiectului fereastră. Dacă îl scrieți astfel: window.setTimeout() , atunci la ce credeți că se referă astfel? Și în consolă vom obține același rezultat! Există mai multe modalități de a rezolva această problemă în ES5. Ne vom uita la cea mai comună: înainte de setTimeout(), voi declara o altă variabilă și voi atribui aceasta ca valoare. Și acum, în corpul funcției, în loc de aceasta, vom indica asta.

    Persoanele = (nume: „Bob”, salut: funcția () ( lasă asta = asta; setTimeout(funcție () ( console.log(„Bună ziua! Numele meu este „ + that.name); console.log(that) ; 2000); persoana.saluta();

    Acum, datorită închiderii, funcția pe care o trimitem către setTimeout() va avea acces la variabila that, a cărei valoare va fi this , adică, în acest caz, obiectul persoană.

    Pentru claritate, puteți vedea la ce se referă asta și aceasta.

    Persoanele = (nume: „Bob”, salut: funcția () ( lasă asta = asta; setTimeout(funcție () ( console.log("Bună! Numele meu este " + that.name); console.log("Este este al meu That = " + that); console.log("Este al meu Acesta = " + asta); ), 2000); ) ); persoana.saluta();

    Vom vedea confirmarea în consolă:

    Vedem că acesta va fi obiectul fereastră - This = , și acesta va fi obiectul nostru persoană - That = .

    În ES6, putem folosi pur și simplu o funcție săgeată pentru a rezolva această problemă.

    Persoanele = ( nume: „Bob”, salut: funcția () ( setTimeout(() => ( console.log(„Bună ziua! Numele meu este „ + acest.nume); console.log(„Este al meu Acest = " + aceasta); ), 2000); ) ); persoana.saluta();

    Ca rezultat, vom vedea în consolă:

    În exemplul grafic, contextul funcției săgeată ar fi obiectul persoană, nu obiectul fereastră. de aceea se va referi la persoană.

    Pe lângă sintaxa compactă, au fost introduse funcții săgeți pentru a rezolva probleme precum acestea.

    Pentru referință, puteți vedea cum a rezolvat Babel acest lucru

    Var person = ( nume: „Bob”, salut: funcția salut() ( var _this = this; setTimeout(function () ( console.log("Bună ziua! Numele meu este " + _this.name); console.log(") Este al meu Acest = " + _acest); ), 2000); ) ); persoana.saluta(); Babel a folosit aceeași metodă pe care am folosit-o în ES5. Singura diferență este că am numit variabila așa, iar Babel a numit-o - _this. Datorită închiderii, funcția pe care o trimitem către setTimeout va avea acces la variabila _this și, ca urmare, la obiectul person.

    Cred că partea cea mai grea a acestei părți este să înțelegem cum funcționează închiderile.

    Mai multe caracteristici ale funcțiilor săgeată:
    Puteți vedea mai multe informații despre funcțiile ES6 și săgeți în postarea mea