begrijp dit, Bind, Call, en toepassen in JavaScript

begrijp dit, Bind, Call, en toepassen in JavaScript

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 thistegenkomen.

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 datthisis 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,thisverwijst 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 undefinedzijn.,

'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 thisgebonden aan de instantie vanCountry, die is opgenomen in deamericaconstante.

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 americais.

"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, zouUncaught TypeError: Cannot read property 'title' of undefined resulteren, aangezienthis zelfundefinedzou zijn.

U kunt echter callen applygebruiken om de thiscontext 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 bookensummarywanneer 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 braveNewWorldSummaryaanroept, zal het altijd de oorspronkelijkethiswaarde 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.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *