Skip to content
Skip to content
Menu
Info Cafe
Info Cafe

Een eenvoudige gids om closures in JavaScript te begrijpen

By admin on januari 20, 2021

Closures in JavaScript zijn een van die concepten waar velen moeite mee hebben. In het volgende artikel zal ik in duidelijke bewoordingen uitleggen wat een closure is, en ik zal het punt naar huis brengen met behulp van eenvoudige codevoorbeelden.

Een closure is een functie in JavaScript waarbij een binnenste functie toegang heeft tot de variabelen van de buitenste (omsluitende) functie – een scope chain.

De closure heeft drie scope chains:

  • hij heeft toegang tot zijn eigen scope – variabelen gedefinieerd tussen de accolades
  • hij heeft toegang tot de variabelen van de buitenste functie
  • hij heeft toegang tot de globale variabelen

Voor niet-ingewijden lijkt deze definitie misschien alleen maar een hoop jargon!

Maar wat is een closure eigenlijk?

Laten we eens kijken naar een eenvoudig closure-voorbeeld in JavaScript:

function outer() { var b = 10;
function inner() {
var a = 20;
console.log(a+b);
}
return inner;
}

Hier hebben we twee functies:

  • een buitenste functie outer die een variabele b heeft, en de inner functie teruggeeft
  • een binnenfunctie inner die een variabele a heeft, en toegang heeft tot een outer variabele b, binnen zijn functielichaam

Het bereik van variabele b is beperkt tot de outer functie, en de reikwijdte van variabele a is beperkt tot de inner functie.

Laten we nu de functie outer() aanroepen, en het resultaat van de functie outer() in een variabele X opslaan. Laten we vervolgens de outer() functie een tweede keer aanroepen en opslaan in variabele Y.

Laten we stap-voor-stap zien wat er gebeurt als de outer() functie voor het eerst wordt aangeroepen:

  1. Variabele b wordt aangemaakt, de reikwijdte ervan wordt beperkt tot de outer() functie, en de waarde ervan wordt ingesteld op 10.
  2. De volgende regel is een functie-declaratie, dus niets om uit te voeren.
  3. Op de laatste regel zoekt return inner naar een variabele genaamd inner, vindt dat deze variabele inner eigenlijk een functie is, en retourneert dus de hele body van de functie inner.
  4. De inhoud die wordt teruggegeven door de return-instructie wordt opgeslagen in X.
    Dus, X slaat het volgende op:
    function inner() {
    var a=20;
    console.log(a+b);
    }
  5. De functie outer() is klaar met uitvoeren, en alle variabelen binnen de scope van outer() bestaan nu niet meer.

Dit laatste deel is belangrijk om te begrijpen. Zodra een functie zijn uitvoering heeft voltooid, houden alle variabelen die binnen het functiebereik zijn gedefinieerd op te bestaan.

De levensduur van een variabele die binnen een functie is gedefinieerd, is de levensduur van de uitvoering van de functie.

Wat dit betekent is dat in console.log(a+b), de variabele b alleen bestaat tijdens de uitvoering van de outer() functie. Zodra de uitvoering van de outer functie is voltooid, bestaat de variabele b niet meer.

Wanneer de functie de tweede keer wordt uitgevoerd, worden de variabelen van de functie opnieuw aangemaakt, en blijven slechts bestaan tot de uitvoering van de functie is voltooid.

Dus, wanneer outer() voor de tweede keer wordt aangeroepen:

  1. Een nieuwe variabele b wordt aangemaakt, de reikwijdte ervan wordt beperkt tot de outer() functie, en de waarde ervan wordt ingesteld op 10.
  2. De volgende regel is een functie-declaratie, dus niets om uit te voeren.
  3. return inner retourneert de gehele body van de functie inner.
  4. De inhoud die door het return statement wordt geretourneerd, wordt opgeslagen in Y.
  5. De functie outer() is klaar met uitvoeren, en alle variabelen binnen de scope van outer() bestaan nu niet meer.

Het belangrijke punt hier is dat wanneer de outer() functie voor de tweede keer wordt aangeroepen, de variabele b opnieuw wordt aangemaakt. Ook wanneer de outer() functie de tweede keer wordt uitgevoerd, houdt deze nieuwe variabele b weer op te bestaan.

Dit is het belangrijkste punt om te beseffen. De variabelen in de functies ontstaan alleen als de functie wordt uitgevoerd, en houden op te bestaan zodra de functie is voltooid.

Nu gaan we terug naar ons codevoorbeeld en kijken naar X en Y. Aangezien de outer() functie bij uitvoering een functie teruggeeft, zijn de variabelen X en Y functies.

Dit kan eenvoudig worden geverifieerd door het volgende aan de JavaScript-code toe te voegen:

console.log(typeof(X)); //X is of type function
console.log(typeof(Y)); //Y is of type function

Omdat de variabelen X en Y functies zijn, kunnen we ze uitvoeren. In JavaScript kan een functie worden uitgevoerd door () achter de functienaam te zetten, zoals X() en Y().

Wanneer we X() en Y() uitvoeren, voeren we in wezen de inner functie uit.

Laten we stap-voor-stap bekijken wat er gebeurt als X() de eerste keer wordt uitgevoerd:

  1. Variabele a wordt aangemaakt, en de waarde ervan wordt ingesteld op 20.
  2. JavaScript probeert nu a + b uit te voeren. Hier wordt het interessant. JavaScript weet dat a bestaat omdat het het zojuist gemaakt heeft. De variabele b bestaat echter niet meer. Aangezien b deel uitmaakt van de buitenste functie, zou b alleen bestaan terwijl de outer() functie in uitvoering is. Aangezien de outer() functie klaar is met uitvoeren lang voordat we X() aanroepen, houden alle variabelen binnen de scope van de outer functie op te bestaan, en dus bestaat variabele b niet meer.

Hoe gaat JavaScript hiermee om?

Closures

De inner functie kan toegang krijgen tot de variabelen van de omsluitende functie door closures in JavaScript. Met andere woorden, de inner functie behoudt de scope chain van de enclosing functie op het moment dat de enclosing functie werd uitgevoerd, en heeft dus toegang tot de variabelen van de enclosing functie.

In ons voorbeeld had de inner functie de waarde van b=10 behouden toen de outer() functie werd uitgevoerd, en bleef deze behouden (sluiten).

Het verwijst nu naar zijn scope chain en merkt op dat het de waarde van variabele b binnen zijn scope chain heeft, omdat het de waarde van b binnen een closure had ingesloten op het moment dat de outer functie was uitgevoerd.

Dus, JavaScript kent a=20 en b=10, en kan a+b berekenen.

U kunt dit verifiëren door de volgende regel code aan het bovenstaande voorbeeld toe te voegen:

Open het Inspect element in Google Chrome en ga naar de Console. U kunt het element uitbreiden om daadwerkelijk het Closure element te zien (weergegeven in de op twee na laatste regel hieronder). Merk op dat de waarde van b=10 behouden blijft in de Closure zelfs nadat de outer() functie zijn uitvoering heeft voltooid.

Variabele b=10 blijft bewaard in de Closure, Closures in Javascript

Laten we nu de definitie van closures die we aan het begin zagen nog eens bekijken en zien of het nu logischer is.

Dus de binnenste functie heeft drie bereikketens:

  • toegang tot zijn eigen scope – variabele a
  • toegang tot de outer variabelen van de functie – variabele b, die het omsloot
  • toegang tot alle globale variabelen die kunnen worden gedefinieerd

Closures in actie

Om het punt van closures duidelijk te maken, laten we het voorbeeld eens uitbreiden met drie regels code:

Wanneer u deze code uitvoert, ziet u de volgende uitvoer in de console.log:

a=20 b=10
a=20 b=11
a=20 b=12
a=20 b=10

Laten we deze code eens stap-voor-stap bekijken om te zien wat er precies gebeurt en om closures in actie te zien!

var X = outer(); // outer() invoked the first time

De functie outer() wordt de eerste keer aangeroepen. De volgende stappen vinden plaats:

  1. Variabele b wordt aangemaakt, en wordt ingesteld op 10
    Variabele c wordt aangemaakt, en ingesteld op 100
    Laten we deze b(first_time) en c(first_time) noemen voor onze eigen referentie.
  2. De inner functie wordt teruggegeven en toegewezen aan X
    Op dit punt, is de variabele b ingesloten binnen de inner functie scope keten als een sluiting met b=10, aangezien inner de variabele b gebruikt.
  3. De functie outer voltooit de uitvoering, en al haar variabelen houden op te bestaan. De variabele c bestaat niet meer, hoewel de variabele b als een afsluiting binnen inner bestaat.

var Y= outer(); // outer() invoked the second time
  1. Variabele b wordt opnieuw aangemaakt en wordt ingesteld op 10
    Variabele c wordt opnieuw aangemaakt.
    Merk op dat hoewel outer() één keer is uitgevoerd voordat de variabelen b en c ophielden te bestaan, zij na uitvoering van de functie zijn aangemaakt als gloednieuwe variabelen.
    Laten we deze b(second_time) en c(second_time) noemen voor onze eigen referentie.
  2. De inner functie wordt teruggegeven en toegewezen aan Y
    Op dit punt wordt de variabele b ingesloten binnen de inner functie scope keten als een sluiting met b(second_time)=10, aangezien inner de variabele b gebruikt.
  3. De outer functie voltooit de uitvoering, en al zijn variabelen houden op te bestaan.
    De variabele c(second_time) bestaat niet meer, hoewel de variabele b(second_time) bestaat als afsluiting binnen inner.

Nu gaan we eens kijken wat er gebeurt als de volgende regels code worden uitgevoerd:

X(); // X() invoked the first time
X(); // X() invoked the second time
X(); // X() invoked the third timeY(); // Y() invoked the first time

Wanneer X() de eerste keer wordt aangeroepen,

  1. variabele a wordt aangemaakt, en ingesteld op 20
  2. de waarde van a=20, de waarde van b is van de sluitingswaarde. b(first_time), dus b=10
  3. variabelen a en b worden opgehoogd met 1
  4. X() voltooit de uitvoering en al zijn binnenste variabelen – variabele a – houden op te bestaan.
    Hoewel, b(first_time) is bewaard gebleven als afsluiting, dus b(first_time) blijft bestaan.

Wanneer X() de tweede keer wordt aangeroepen,

  1. variabele a wordt opnieuw aangemaakt, en ingesteld op 20
    Een eventuele eerdere waarde van variabele a bestaat niet meer, omdat deze ophield te bestaan toen X() de uitvoering de eerste keer voltooide.
  2. de waarde van a=20
    de waarde van b is overgenomen van de sluitingswaarde – b(first_time)
    Merk ook op dat we de waarde van b hadden verhoogd met 1 van de vorige uitvoering, dus b=11
  3. variabelen a en b worden verhoogd met 1 opnieuw
  4. X() voltooit de uitvoering en al zijn binnenste variabelen – variabele a – houden op te bestaan
    Hoewel, b(first_time) blijft bewaard omdat de afsluiting blijft bestaan.

Wanneer X() voor de derde keer wordt aangeroepen,

  1. variabele a wordt opnieuw aangemaakt, en ingesteld op 20
    Een eventuele eerdere waarde van variabele a bestaat niet meer, omdat deze ophield te bestaan toen X() de uitvoering de eerste keer voltooide.
  2. de waarde van a=20, de waarde van b is van de sluitingswaarde – b(first_time)
    Merk ook op dat we de waarde van b hadden verhoogd met 1 bij de vorige uitvoering, dus b=12
  3. variabelen a en b worden door 1 weer verhoogd
  4. X() voltooit de uitvoering en al zijn binnenste variabelen – variabele a – houden op te bestaan
    Het b(first_time) blijft echter behouden omdat de closure blijft bestaan

Wanneer Y() voor de eerste keer wordt aangeroepen,

  1. variabele a wordt opnieuw aangemaakt, en ingesteld op 20
  2. de waarde van a=20, de waarde van b is van de sluitingswaarde – b(second_time), dus b=10
  3. variabelen a en b worden verhoogd met 1
  4. Y() voltooit de uitvoering, en al zijn binnenste variabelen – variabele a – houden op te bestaan
    Het b(second_time) is echter bewaard gebleven als afsluiting, dus b(second_time) blijft bestaan.

Slotopmerkingen

Sluitingen zijn een van die subtiele concepten in JavaScript die in het begin moeilijk te begrijpen zijn. Maar als je ze eenmaal begrijpt, realiseer je je dat het niet anders had gekund.

Hopelijk heeft deze stap-voor-stap uitleg je geholpen om het concept van closures in JavaScript echt te begrijpen!

Andere artikelen:

  • Een snelle gids voor “self invoking” functies in Javascript
  • Het begrijpen van Functie scope vs. Blok scope in Javascript
  • Hoe gebruik je Beloftes in JavaScript
  • Hoe bouw je een eenvoudige Sprite animatie in JavaScript

Berichtnavigatie

Aric Almirola, Smithfield verlengen contract met Stewart-Haas Racing
Wat is blackface?

Geef een reactie Antwoord annuleren

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

Meest recente berichten

  • 9 Beste Vitaminen en Supplementen voor honden voor een betere gezondheid
  • CD-rentevoorspelling voor 2021: Tarieven blijven waarschijnlijk laag, maar kunnen later in het jaar stijgen
  • Hoe de documentatie van het kwaliteitsmanagementsysteem te structureren
  • Chronische bekkenpijn en prostatitis: symptomen, diagnose en behandeling
  • Mixed Berry Crisp
  • Koolhydraatarm chocoladepuddingrecept
  • Gezonde spelletjes en activiteiten voor kinderen | UIC Online Informatics
  • De voordelen van borstvoeding na één jaar
  • Is het veilig om koffiedik door de gootsteen te spoelen | Atomic Plumbing
  • Onze werkzaamheden

Meta

  • Inloggen
  • Berichten feed
  • Reacties feed
  • WordPress.org

Archief

  • maart 2021
  • februari 2021
  • januari 2021
  • december 2020
  • DeutschDeutsch
  • NederlandsNederlands
  • EspañolEspañol
  • FrançaisFrançais
  • PortuguêsPortuguês
  • ItalianoItaliano
  • PolskiPolski
  • 日本語日本語
©2021 Info Cafe | WordPress Theme by SuperbThemes.com