înțelegerea acest lucru, Bind, apel, și se aplică în JavaScript

înțelegerea acest lucru, Bind, apel, și se aplică în JavaScript

Acest articol a fost scris inițial pentru DigitalOcean.

this cuvinte cheie este un concept foarte important în JavaScript, și, de asemenea, un deosebit de confuz la ambele noi dezvoltatori și cei care au experiență în alte limbaje de programare. În JavaScript, this este o referință la un obiect., Obiectul care this se referă la pot varia, implicit, în funcție de dacă este la nivel global, pe un obiect, sau într-un constructor, și, de asemenea, poate varia în mod explicit bazate pe utilizarea de Function metode prototip bind, call, și apply.

deșithis este un subiect complex, este, de asemenea, unul care apare imediat ce începeți să scrieți primele programe JavaScript., Dacă sunteți încercarea de a accesa un element sau eveniment în Document Object Model (DOM), construirea de clase pentru scris în programarea orientată pe obiecte în stil, sau folosind proprietatile si metodele obișnuite obiecte, veți întâlni this.

În acest articol, veți afla ce this se referă la implicit în funcție de context, și veți învăța cum să utilizați bind, call, și apply metode de a determina în mod explicit valoarea this.,

Implicit Context

Există patru principale contexte în care valoarea de this poate fi implicit deduce:

  • contextul global
  • ca metodă într-un obiect
  • ca un constructor pe o funcție sau de clasă
  • ca un DOM de tratare a evenimentului

Global

În context global, this se referă la obiect global. Când lucrați într-un browser, contextul global este window. Când lucrați în nod.js, contextul global este global.,

Notă: Dacă nu sunteți încă familiarizați cu conceptul de aplicare în JavaScript, vă rugăm să consultați Înțelegerea Variabile, domeniul de Aplicare și de Ridicare în JavaScript.

pentru exemple, veți exersa codul în consola de instrumente pentru dezvoltatori a browserului. Citiți Cum să utilizați Consola pentru dezvoltatori JavaScript dacă nu sunteți familiarizat cu rularea codului JavaScript în browser.

Dacă înregistrați valoarea this fără alt cod, veți vedea la ce obiect se referă this.,

console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

puteți vedea că this este window, care este obiectul global al unui browser.

în înțelegerea variabilelor, domeniul de aplicare și ridicarea în JavaScript, ați învățat că funcțiile au propriul context pentru variabile. S-ar putea să fiți tentat să credeți că this ar urma aceleași reguli în interiorul unei funcții, dar nu. O funcție de nivel superior va păstra în continuare referința this a obiectului global.,

de a scrie un nivel superior funcție, sau o funcție care nu este asociat cu orice obiect, cum ar fi acest lucru:

function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

Chiar și într-o funcție, this încă se referă la window sau obiect global.

cu toate Acestea, atunci când se utilizează modul strict, contextul this în funcție de contextul global va fi undefined.,

'use strict'function printThis() { console.log(this)}printThis()
undefined

în General, este mai sigur de a utiliza modul strict pentru a reduce probabilitatea de this având o neașteptată domeniul de aplicare. Rar va vrea cineva să se refere la window obiect folosind this.

Pentru mai multe informații despre modul strict și ce schimbări face în ceea ce privește greșelile și securitatea, citiți documentația modului Strict pe MDN.,

o metodă obiect

o metodă este o funcție pe un obiect, sau o sarcină pe care un obiect poate efectua. O metodă utilizează this pentru a se referi la proprietățile obiectului.

"The United States of America was founded in 1776."

În acest exemplu, this este același lucru ca america.

într-un obiect imbricat, this se referă la obiectul curent al metodei. În următorul exemplu, this.symbol în details obiect se referă la details.symbol.,

"The symbol is the eagle and the currency is USD."

un Alt mod de gândire despre el este că this se referă la obiectul pe partea stângă a dot când apelați o metodă.

un constructor de funcții

când utilizați cuvântul cheie new, creează o instanță a unei funcții sau clase de constructor. Constructorii de funcții au fost modul standard de inițializare a unui obiect definit de utilizator înainte ca sintaxa class să fie introdusă în actualizarea ECMAScript 2015 la JavaScript., În înțelegerea claselor în JavaScript, veți învăța cum să creați un constructor de funcții și un constructor de clase echivalente.

"The United States of America was founded in 1776."

În acest context, this este acum legat la instanța de Country, care este conținută în america constanta.

un Constructor de clasă

un constructor pe o clasă acționează la fel ca un constructor pe o funcție. Citiți mai multe despre asemănările și diferențele dintre constructorii de funcții și clasele ES6 în înțelegerea claselor în JavaScript.,

this în describe metoda se referă la instanța de Country, care este america.

"The United States of America was founded in 1776."

un Handler de evenimente DOM

în browser, există un context special this pentru manipulatorii de evenimente. Într-un handler eveniment numit de addEventListener, this va referi la event.currentTarget., Mai des decât nu, dezvoltatorii vor folosi pur și simplu event.target sau event.currentTarget după cum este necesar pentru a accesa elementele din DOM, dar din moment ce this de referință modificări în acest context, este important să se cunoască.

în exemplul următor, vom crea un buton, vom adăuga text la acesta și îl vom adăuga la DOM. Când înregistrăm valoarea this în cadrul manipulatorului de evenimente, acesta va imprima ținta.,după ce inserați acest lucru în browser-ul dvs., veți vedea un buton atașat la pagina care spune „Faceți clic pe mine”. Dacă faceți clic pe butonul, veți vedea <button>Click me</button> apar în consola, ca făcând clic pe butonul busteni elementul, care este butonul în sine. Prin urmare, după cum puteți vedea, this se referă la elementul vizat, care este elementul la care am adăugat un ascultător de evenimente.,

context Explicit

în toate exemplele anterioare, valoarea this a fost determinată de contextul său—indiferent dacă este global, într-un obiect, într-o funcție sau clasă construită sau pe un handler de evenimente DOM. Cu toate acestea, folosind call, apply sau bind, puteți determina în mod explicit ceea ce this ar trebui să se refere la.,

este dificil să se definească exact când să folosească call, apply sau bind, deoarece aceasta va depinde de contextul de program. bind poate fi deosebit de util atunci când doriți să utilizați evenimente pentru a accesa proprietățile unei clase în cadrul unei alte clase. De exemplu, dacă ar fi să scrie un joc simplu, s-ar putea separa interfața cu utilizatorul și i/o într-o singură clasă, și logica de joc și de stat în alta., Deoarece jocul de logica ar avea nevoie pentru a accesa de intrare, cum ar fi apăsați tasta și faceți clic pe, ce-ar vrea să bind evenimente pentru a accesa this valoare de joc de logica de clasa.

important este să știți cum pentru a determina ce obiect this se referă la, pe care le puteți face implicit cu ceea ce ai învățat în secțiunile anterioare, sau în mod explicit cu cele trei metode pe care le vor învăța în continuare.,

Apel și se Aplică

call și apply sunt foarte similare—se invoca o funcție cu un anumit this context, și argumente opționale. Singura diferență între call și apply este că call necesită argumente pentru a fi trecut în una câte una, și apply ia argumente ca o matrice.,

În acest exemplu, vom crea un obiect, și de a crea o funcție care trimiterile this dar nu are nici un this context.

"undefined was written by undefined"

Deoarece summary și book au nici o legătură, invocând summary de la sine se va imprima numai undefined, așa cum este în căutarea pentru acele proprietăți pe obiect global.,

Notă: Încearcă acest lucru în mod strict ar duce la Uncaught TypeError: Cannot read property 'title' of undefined, ca this în sine ar fi undefined.

cu toate Acestea, puteți utiliza call și apply să invoce this contextul book pe funcție.,

summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."

acum Există o legătură între book și summary când aceste metode sunt aplicate. Să confirmăm exact ce este this.

function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}

În acest caz, this de fapt, devine obiectul transmis ca argument.

call și apply sunt aceleași, dar există o mică diferență., În plus față de posibilitatea de a trece this context ca primul argument, puteți trece, de asemenea, argumente suplimentare prin.

function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}

Cu call fiecare valoare suplimentară pe care doriți să treci este trimis ca un argument suplimentar.,

longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

Dacă încercați să trimiteți exact aceleași argumente cu apply, aceasta este ceea ce se întâmplă:

longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15

în Schimb, pentru apply, trebuie să treci toate argumentele într-o matrice.

longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

diferența între trece argumentele în mod individual sau într-o matrice este subtil, dar e important să fie conștienți de., Ar putea fi mai simplu și mai convenabil să folosiți apply, deoarece nu ar necesita schimbarea apelului de funcție dacă s-ar schimba unele detalii ale parametrilor.

Bind

Ambele call și apply sunt un timp de utilizare de metode—dacă ai apela metoda cu this context, va avea, dar funcția originală va rămâne neschimbată.,

Uneori, poate fi necesar să utilizați o metodă de peste si peste, cu this context de un alt obiect, și în acest caz, ai putea folosi bind metoda de a crea un brand nou funcția cu un legat în mod explicit this.

const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"

În acest exemplu, de fiecare dată când te sun braveNewWorldSummary, se va întoarce întotdeauna original this valoarea obligat să-l., Încercarea de a lega o nouă this context va eșua, astfel încât să puteți avea încredere întotdeauna un legat funcția să returneze this valoarea pe care o așteptați.

Deși acest exemplu, încearcă să-l lega braveNewWorldSummary încă o dată, se păstrează în original this context de prima dată, acesta a fost obligat.

funcții săgeată

funcții săgeată nu au propriile lorthis legare. În schimb, ei merg până la următorul nivel de execuție.,

poate fi util să folosiți funcția săgeată în cazurile în care doriți cu adevărat this pentru a vă referi la contextul exterior. De exemplu, dacă ați avea un ascultător de evenimente în interiorul unei clase, probabil că ați dori ca this să se refere la o anumită valoare din clasă.

în acest exemplu, veți crea și adăuga butonul la DOM ca înainte, dar clasa va avea un ascultător de evenimente care va schimba valoarea textului butonului atunci când faceți clic.

dacă faceți clic pe buton, conținutul textului se va schimba la valoarea buttonText., Dacă nu ai fi folosit o săgeată funcție de aici, this va fi egal cu event.currentTarget, și nu veți fi capabil să-l folosească pentru a accesa o valoare în clasă, fără explicit obligatorii ea. Această tactică este adesea folosită pe metode de clasă în cadre precum React.

Concluzie

În acest articol, ai învățat despre this în JavaScript, și multe valori diferite ar fi bazat pe implicită runtime obligatoriu și explicit obligatoriu prin bind, call și apply., De asemenea, ați aflat despre modul în care lipsa this legarea în funcțiile săgeată poate fi utilizată pentru a se referi la un context diferit. Cu aceste cunoștințe, ar trebui să puteți determina valoarea this în programele dvs.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *