Fullt forstå dette søkeordet

Dagens veiledning kommer med hilsen til den talentfulle Cody Lindley, fra sin gratis eBok: JavaScript-opplysning. Han diskuterer forvirrende dette søkeord, og de ulike måtene for å bestemme og sette verdien.

Publisert opplæring

Noen få uker besøker vi noen av leserens favorittinnlegg fra hele historien til nettstedet. Denne opplæringen ble først publisert i juli 2011.


Konseptuell oversikt over dette

Når en funksjon opprettes, opprettes et søkeord som kalles dette, (bak kulissene), som kobler til objektet der funksjonen opererer. Sa en annen måte, dette er tilgjengelig for omfanget av sin funksjon, men er en referanse til objektet som den funksjonen er en eiendom / metode.

La oss ta en titt på dette objektet:

 

Notice hvordan innsiden av getGender funksjon, får vi tilgang til kjønnsegenskapen ved hjelp av punktnotasjon (f.eks cody.gender) på selve cody-objektet. Dette kan skrives om ved hjelp av dette for å få tilgang til cody objekt fordi dette peker til cody gjenstand.

 

De dette brukt i this.gender bare refererer til cody objekt som funksjonen er på
drifts.

Emnet for dette kan være forvirrende, men det trenger ikke å være. Bare husk det, generelt, dette brukes inne i funksjoner for å referere til objektet som funksjonen er inne i, i motsetning til selve funksjonen (unntak inkluderer bruk av ny søkeord eller anrop() og søke om()).

Viktige notater

  • Søkeordet dette ser ut og virker som en hvilken som helst annen variabel, bortsett fra at du ikke kan endre den.
  • - I motsetning til argumenter og eventuelle parametere sendt til funksjonen, dette er et søkeord (ikke en eiendom) i anrops- / aktiveringsobjektet.

Hvordan er verdien av dette Fast bestemt?

Verdien av dette, bestått til alle funksjoner, er basert på konteksten der funksjonen kalles på kjøretid. Vær oppmerksom her, fordi dette er en av de som du bare trenger å huske.

De myObject objekt i koden under er gitt en eiendom som kalles sayFoo, som peker på sayFoo funksjon. Når sayFoo funksjon kalles fra det globale omfanget, dette refererer til vinduet objektet. Når det kalles som en metode for myObject, dette refererer til myObject.

Since myObject har en eiendom som heter foo, den egenskapen blir brukt.

 

Klart, verdien av dette er basert på konteksten der funksjonen blir kalt. Tenk på at begge myObject.sayFoo og sayFoo pek på samme funksjon. Men avhengig av hvor (dvs. konteksten) sayFoo () er kalt fra, verdien av dette er annerledes.

Hvis det hjelper, her er den samme koden med hodeobjektet (dvs. vindu) eksplisitt brukt.

 

Pass på at når du overfører funksjoner, eller har flere referanser til en funksjon, innser du at verdien av dette vil forandre avhengig av konteksten der du ringer funksjonen.

Viktig notat

  • Alle variabler unntatt dette og argumenter følger leksikalsk omfang.

De dette Søkeord refererer til hovedobjektet i nestede funksjoner

Du lurer kanskje på hva som skjer med dette når den brukes inne i en funksjon som finnes inne i en annen funksjon. Den dårlige nyheten er i ECMA 3, dette mister sin vei og refererer til hodetobjektet (vindu objekt i nettlesere), i stedet for objektet der funksjonen er definert.


I koden nedenfor, dette inni func2 og func3 mister sin vei og refererer ikke til myObject men i stedet for hodet objektet.

 

Den gode nyheten er at dette vil bli løst i ECMAScript 5. For nå bør du være oppmerksom på dette problemet, spesielt når du begynner å overføre funksjoner som verdier til andre funksjoner.

Vurder koden nedenfor og hva som skjer når du overfører en anonym funksjon til foo.func1. Når den anonyme funksjonen kalles inne i foo.func1 (en funksjon inne i en funksjon) dette Verdien inne i den anonyme funksjonen vil være en referanse til hodeobjektet.

 

Nå vil du aldri glemme: dette verdien vil alltid være en referanse til hodeobjektet når vertsfunksjonen er innkapslet inne i en annen funksjon eller påkrevd i sammenheng med en annen funksjon (igjen er dette løst i ECMAScript 5).


Fungerer rundt det nestede funksjonsproblemet

Slik at dette verdien går ikke tapt, du kan bare bruke omfanget kjeden for å holde en referanse til dette i foreldrefunksjonen. Koden nedenfor viser hvordan du bruker en variabel som heter at, og utnytte omfanget, kan vi holde øye med funksjonskonteksten bedre.


Kontrollerer verdien av dette

Verdien av dette er normalt bestemt fra konteksten der en funksjon kalles (unntatt når ny søkeord brukes - mer om det om et minutt), men du kan overskrive / kontrollere verdien av dette ved hjelp av søke om() eller anrop() å definere hvilket objekt dette peker til når man påkaller en funksjon. Å bruke disse metodene er som å si: "Hei, ring X-funksjon, men fortell funksjonen å bruke Z-objektet som verdien for dette."Ved å gjøre det, er standard måten som JavaScript bestemmer verdien av dette er overstyrt.

Nedenfor oppretter vi et objekt og en funksjon. Vi kaller deretter funksjonen via anrop() slik at verdien av dette inne i funksjonen bruker myObject som sin sammenheng. Erklæringene inne i myFunction funksjonen vil da fylle seg myObject med egenskaper i stedet for å fylle hodeobjektet. Vi har endret objektet til hvilket dette (inni myFunction) refererer.

 

I eksemplet ovenfor bruker vi anrop(), men søke om() kan også brukes. Forskjellen mellom de to er hvordan parametrene for funksjonen er bestått. Ved hjelp av anrop(), Parametrene er bare kommaseparerte verdier. Ved hjelp av søke om(), Parameterverdiene sendes inne i en matrise. Nedenfor er den samme ideen, men bruker søke om().

 

Det du trenger å ta bort her er at du kan overstyre standard måten som JavaScript bestemmer verdien av dette i funksjonens omfang.


Bruker dette Søkeord inne i en brukerdefinert konstruksjonsfunksjon

Når en funksjon er påkalt med ny søkeord, verdien av dette - som det er sagt i konstruktøren - refererer til forekomsten selv. Sa en annen måte: i konstruktørfunksjonen kan vi utnytte objektet via dette før objektet faktisk er opprettet. I dette tilfellet er standardverdien for dette endrer seg på en måte som ikke er i motsetning til bruk anrop() eller søke om().

Nedenfor oppretter vi en Person konstruktørfunksjon som bruker dette for å referere til et objekt som opprettes. Når en forekomst av Person er skapt, this.name vil referere til det nyopprettede objektet og plassere en eiendom som heter Navn i det nye objektet med en verdi fra parameteren (Navn) bestått til konstruktørfunksjonen.

 

En gang til, dette refererer til "objektet som skal være" når konstruktørfunksjonen påberopes ved hjelp av ny søkeord. Hadde vi ikke brukt ny søkeord, verdien av dette ville være konteksten der Person er påkalt - i dette tilfellet hodeobjektet. La oss undersøke dette scenariet.

 

Søkeordet dette Inne i en prototypemetode refererer til en Constructor-forekomst

Når det brukes i funksjoner lagt til en konstruktør prototype eiendom, dette refererer til forekomsten som metoden er påkalt på. Si at vi har en skikk Person() konstruktør funksjon. Som en parameter krever det personens fulle navn. Hvis vi trenger tilgang til personens fulle navn, legger vi til en whatIsMyFullName metode til Person.prototype, slik at alt Person tilfeller arver metoden. Når du bruker dette, Metoden kan referere til forekomsten som påkaller den (og dermed dens egenskaper).

Her demonstrerer jeg opprettelsen av to Person objekter (cody og lisa) og den arvede whatIsMyFullName Metode som inneholder dette søkeordet for å få tilgang til forekomsten.

 

Ta bort her er det søkeordet dette brukes til å referere til forekomster når det brukes inne i en metode som finnes i prototype gjenstand. Hvis forekomsten ikke inneholder eiendommen, begynner prototypeoppslaget.

Merknader

- Hvis forekomsten eller objektet pekte på dette inneholder ikke eiendommen som refereres, de samme reglene som gjelder for eiendomsoppslag blir brukt og eiendommen blir "sett opp" på prototypekjeden. Så i vårt eksempel, hvis fullt navn Egenskapen var ikke inneholdt i vårt eksempel da fullt navn ville bli sett på Person.prototype.fullName deretter Object.prototype.fullName.


Les boken gratis!

Denne boken handler ikke om JavaScript-mønster eller implementering av et objektorientert paradigme med JavaScript-kode. Det var ikke skrevet for å skille de gode funksjonene til JavaScript-språket fra de dårlige. Det er ikke ment å være en komplett referanseguide. Det er ikke rettet mot folk som er nye til programmering eller de helt nye til JavaScript. Det er heller ikke en kokebok med JavaScript-oppskrifter. Disse bøkene er skrevet.