Dit artikel is oorspronkelijk geschreven voor DigitalOcean.
het this
sleutelwoord is een zeer belangrijk concept in JavaScript, en ook een bijzonder verwarrend concept voor zowel nieuwe ontwikkelaars als degenen die ervaring hebben met andere programmeertalen. In JavaScript is this
een verwijzing naar een object., Het object waarnaar this
verwijst, Kan impliciet variëren op basis van of het Globaal is, op een object of in een constructor, en kan ook expliciet variëren op basis van het gebruik van de Function
prototype methoden bind
, call
, en apply
.
hoewel this
Een beetje een complex onderwerp is, is het ook een onderwerp dat verschijnt zodra u begint met het schrijven van uw eerste JavaScript-programma ‘ s., Of u nu probeert toegang te krijgen tot een element of gebeurtenis in het Document Object Model (DOM), klassen bouwt voor het schrijven in de objectgeoriënteerde programmeerstijl, of de eigenschappen en methoden van gewone objecten gebruikt, u zult this
tegenkomen.
in dit artikel leer je waarnaar this
verwijst impliciet gebaseerd op context, en leer je hoe je de bind
, call
, en apply
methoden gebruikt om expliciet de waarde van .,
Impliciete Context
Er zijn vier belangrijke contexten waarin de waarde van this
kan impliciet worden afgeleid:
- de globale context
- als een methode binnen een object
- als een constructor op een functie of klasse
- als een DOM gebeurtenis-handler
Global
In de globale context this
‘ verwijst naar de wereldwijde object. Wanneer u in een browser werkt, is de globale context window
. Als je in Node werkt.js, de globale context is global
.,
Opmerking: Als u nog niet bekend bent met het concept scope in JavaScript, bekijk dan het begrip variabelen, Scope en hijsen in JavaScript.
voor de voorbeelden zult u de code oefenen in de console Developer Tools van de browser. Lees hoe u de JavaScript Developer Console gebruikt als u niet bekend bent met het uitvoeren van JavaScript-code in de browser.
Als u de waarde van this
zonder enige andere code registreert, zult u zien naar welk object this
verwijst.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
u kunt zien datthis
is window
, het globale object van een browser.
bij het begrijpen van variabelen, Scope en hijsen in JavaScript, leerde u dat functies hun eigen context voor variabelen hebben. Je zou geneigd kunnen zijn te denken dat this
dezelfde regels zou volgen binnen een functie, maar dat is niet het geval. Een top-level functie behoudt nog steeds dethis
referentie van het globale object.,
u schrijft een top-level functie, of een functie die niet geassocieerd is met een object, zoals dit:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
zelfs binnen een functie,this
verwijst nog steeds naar de window
, of globaal object.
echter, bij gebruik van de strikte modus, zal de context van this
binnen een functie op de globale context undefined
zijn.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
over het algemeen is het veiliger om de strikte modus te gebruiken om de kans te verkleinen dat this
een onverwachte scope heeft. Zelden zal iemand naar het window
object willen verwijzen met this
.
voor meer informatie over strict mode en welke wijzigingen het maakt met betrekking tot fouten en beveiliging, lees de Strict mode documentatie op MDN.,
een Objectmethode
een methode is een functie op een object, of een taak die een object kan uitvoeren. Een methode gebruikt this
om te verwijzen naar de eigenschappen van het object.
"The United States of America was founded in 1776."
in dit voorbeeld is this
hetzelfde als america
.
in een genest object verwijst this
naar het huidige objectbereik van de methode. In het volgende voorbeeld verwijst this.symbol
binnen het details
object naar details.symbol
.,
"The symbol is the eagle and the currency is USD."
een andere manier van denken is dat this
verwijst naar het object aan de linkerkant van de punt wanneer een methode wordt aangeroepen.
een Function Constructor
wanneer u het new
sleutelwoord gebruikt, wordt een instantie van een constructorfunctie of-klasse aangemaakt. Function constructors waren de standaard manier om een door de gebruiker gedefinieerd object te initialiseren voordat de syntaxis class
werd geïntroduceerd in de ECMAScript 2015 update naar JavaScript., In het begrijpen van klassen in JavaScript, leert u hoe u een functie constructor en een gelijkwaardige klasse constructor te creëren.
"The United States of America was founded in 1776."
in deze context is this
gebonden aan de instantie vanCountry
, die is opgenomen in deamerica
constante.
een klasse-Constructor
een constructor op een klasse werkt hetzelfde als een constructor op een functie. Lees meer over de overeenkomsten en verschillen tussen functie constructors en ES6 klassen in het begrijpen van klassen in JavaScript.,
this
in de describe
methode verwijst naar de instantie van Country
, wat america
is.
"The United States of America was founded in 1776."
een dom Event Handler
In de browser is er een speciale this
context voor event handlers. In een gebeurtenisafhandeling die wordt aangeroepen door addEventListener
, zal this
verwijzen naar event.currentTarget
., Vaker wel dan niet, zullen ontwikkelaars gewoon event.target
of event.currentTarget
gebruiken als dat nodig is om toegang te krijgen tot elementen in het DOM, maar aangezien de this
referentiewijzigingen in deze context, is het belangrijk om te weten.
in het volgende voorbeeld maken we een knop aan, voegen er tekst aan toe en voegen deze toe aan de DOM. Wanneer we de waarde van this
in de event handler loggen, zal het doel worden afgedrukt.,
<button>Click me</button>
zodra u dit in uw browser plakt, ziet u een knop toegevoegd aan de pagina waarop staat”klik op mij”. Als u op de knop klikt, ziet u <button>Click me</button>
verschijnen in uw console, als u op de knop klikt logt het element, dat de knop zelf is. Daarom, zoals je kunt zien, verwijst this
naar het doelelement, dat het element is waaraan we een event listener hebben toegevoegd.,
expliciete Context
in alle voorgaande voorbeelden werd de waarde vanthis
bepaald door zijn context—of het nu globaal is, in een object, in een geconstrueerde functie of klasse, of op een dom event handler. Echter, met call
, apply
, of bind
, kunt u expliciet bepalen waarnaar this
moet verwijzen.,
het is moeilijk om precies te bepalen wanneer call
, apply
, of bind
moet worden gebruikt, omdat dit afhankelijk is van de context van uw programma. bind
kan bijzonder nuttig zijn wanneer u gebeurtenissen wilt gebruiken om eigenschappen van een klasse binnen een andere klasse te benaderen. Bijvoorbeeld, als je een eenvoudig spel zou schrijven, zou je de gebruikersinterface en I/O kunnen scheiden in een klasse, en de spellogica en status in een andere., Omdat de spellogica toegang moet hebben tot invoer, zoals toetsdrukken en Klikken, wilt u bind
de gebeurtenissen om toegang te krijgen tot de this
waarde van de spellogic class.
het belangrijkste is om te weten hoe te bepalen naar welk object this
verwijst, wat je impliciet kunt doen met wat je geleerd hebt in de vorige secties, of expliciet met de drie methoden die je hierna leert.,
aanroepen en toepassen
call
en apply
zijn zeer vergelijkbaar—ze roepen een functie aan met een opgegeven this
context, en optionele argumenten. Het enige verschil tussen call
en apply
is dat call
vereist dat de argumenten één voor één worden doorgegeven, en apply
neemt de argumenten als een array.,
in dit voorbeeld maken we een object en een functie die verwijst naar this
maar geen this
context heeft.
"undefined was written by undefined"
aangezien summary
en book
geen verbinding hebben, als summary
wordt aangeroepen, wordt alleen undefined
, omdat het op zoek is naar die eigenschappen op het globale object.,
Opmerking: Als dit in strikte modus wordt geprobeerd, zou
Uncaught TypeError: Cannot read property 'title' of undefined
resulteren, aangezienthis
zelfundefined
zou zijn.
U kunt echter call
en apply
gebruiken om de this
context van book
op de functie aan te roepen.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
er is nu een verbinding tussen book
ensummary
wanneer deze methoden worden toegepast. Laten we precies bevestigen wat this
is.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
in dit geval wordt this
het object dat als argument wordt doorgegeven.
Dit is hoe call
en apply
hetzelfde zijn, maar er is één klein verschil., Naast de mogelijkheid om de this
context als het eerste argument door te geven, kunt u ook extra argumenten doorgeven.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
met call
elke extra waarde die u wilt doorgeven wordt verzonden als een extra argument.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Als je probeert te verzenden exact dezelfde argumenten met apply
dit is wat er gebeurt:
longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
in Plaats van apply
je moet passeren alle argumenten in een array.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
het verschil tussen het doorgeven van de argumenten afzonderlijk of in een array is subtiel, maar het is belangrijk om je bewust te zijn., Het kan eenvoudiger en handiger zijn om apply
te gebruiken, omdat het niet nodig zou zijn de functie aanroep te veranderen als sommige parameterdetails zouden veranderen.
Bind
beide call
en apply
zijn eenmalige gebruiksmethoden-als u de methode aanroept met de this
context zal het het hebben, maar de oorspronkelijke functie blijft ongewijzigd.,
soms moet u een methode steeds opnieuw gebruiken met dethis
context van een ander object, en in dat geval kunt u debind
methode gebruiken om een gloednieuwe functie aan te maken met een expliciet gebondenthis
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
in dit voorbeeld, elke keer als u braveNewWorldSummary
aanroept, zal het altijd de oorspronkelijkethis
waarde retourneren., Een poging om een nieuwe this
context eraan te binden zal mislukken, dus u kunt altijd vertrouwen op een gebonden functie om de this
waarde te retourneren die u verwacht.
hoewel dit voorbeeld braveNewWorldSummary
opnieuw probeert te binden, behoudt het de oorspronkelijke this
context vanaf de eerste keer dat het werd gebonden.
Pijlfuncties
Pijlfuncties hebben geen eigen this
binding. In plaats daarvan gaan ze naar het volgende niveau van uitvoering.,
Het kan nuttig zijn om de pijlfunctie te gebruiken in gevallen waarin u wilt dat this
naar de buitenste context verwijst. Als u bijvoorbeeld een gebeurtenisluisteraar in een klasse had, zou u waarschijnlijk willen dat this
verwijst naar een waarde in de klasse.
in dit voorbeeld maakt u een knop aan en voegt u deze toe aan de DOM zoals eerder, maar de klasse heeft een gebeurtenisluisteraar die de tekstwaarde van de knop zal veranderen wanneer erop wordt geklikt.
Als u op de knop klikt, zal de tekstinhoud veranderen in de waarde van buttonText
., Als u hier geen pijlfunctie had gebruikt, zou this
gelijk zijn aan event.currentTarget
, en u zou het niet kunnen gebruiken om toegang te krijgen tot een waarde binnen de klasse zonder deze expliciet te binden. Deze tactiek wordt vaak gebruikt op Klasse methoden in kaders zoals React.
conclusie
In dit artikel leerde u overthis
in JavaScript, en de vele verschillende waarden die het zou kunnen hebben gebaseerd op impliciete runtime binding, en expliciete binding viabind
,call
, enapply
., U heeft ook geleerd hoe het ontbreken vanthis
binding in arrow-functies kan worden gebruikt om naar een andere context te verwijzen. Met deze kennis zou u in staat moeten zijn om de waarde van this
in uw programma ‘ s te bepalen.