Articles

Hoe JavaScript-sluitingen werken, in gewoon Nederlands

JavaScript is een veelgebruikte taal waarmee je van alles kunt bouwen, van een eenvoudige landingspagina tot een full-stack productietoepassing. Naarmate JavaScript en programmeren in het algemeen zich verder ontwikkelden, realiseerden ontwikkelaars zich dat het paradigma van objectgeoriënteerd programmeren (OOP) voor de meeste toepassingen onwenselijk is. Functioneel programmeren kwam naar voren als de oplossing voor veel van de pijnpunten van OOP.

Closures zijn een veelbesproken onderwerp in de wereld van functioneel programmeren, maar ze worden vaak losjes en in technisch jargon gedefinieerd. We zullen hier ons best doen om in lekentaal uit te leggen hoe JavaScript closures werken.

Aan het eind van deze tutorial moet je het volgende begrijpen:

  • Hoe je closures herkent
  • Wat een closure is en hoe deze zich gedraagt ten opzichte van de uitvoeringscontext en de aanroepstack
  • Common use cases voor closures

Uitleg JavaScript closures

We beginnen met te laten zien hoe een closure eruitziet.

Probeer de code maar eens zelf uit te voeren. Technisch gezien retourneert de functie met de naam makeCounter een andere functie met de naam increment. Deze increment functie heeft toegang tot de count variabele, zelfs nadat de makeCount functie is uitgevoerd. Een deel van de sluiting is hier de count variabele; deze is beschikbaar voor de increment functie wanneer deze is gedefinieerd, zelfs nadat makeCounter is voltooid. Het andere deel is de increment functie.

Stel je voor dat je een huis hebt en een tuin die er omheen ligt. Zodra je de deur naar de tuin opent en sluit, kun je hem niet meer openen – de tuin wordt ontoegankelijk. Je hebt honger en gelukkig staan er een sinaasappelboom en een appelboom in je tuin. Je neemt een zakje, plukt een sinaasappel en een appel, en gaat terug je huis in. Je kunt niet meer naar buiten

Nu, als je eenmaal in je huis bent, kun je de sinaasappel of appel uit het zakje pakken en opeten wanneer je weer honger krijgt. Het kleine zakje in dit voorbeeld is de sluiting. Een closure bevat alle variabelen en functies die je tot je beschikking had toen je in de tuin was, ook als je binnen in het huis bent en niet meer naar buiten kunt.

Laten we eens kijken hoe dit in code uitpakt:

Omdat de fruits variabele beschikbaar is voor de teruggegeven functie wanneer makeFruitGarden wordt uitgevoerd, worden de fruits variabele en de binnenste functie de closure. Wanneer consumeFruit wordt uitgevoerd, wordt een fruit – het laatste element uit de fruits array omdat pop() wordt gebruikt – geretourneerd. Als beide vruchten zijn geconsumeerd/opgegeten, blijft er niets meer over om op te eten.

Lexical scope

Om closures echt te begrijpen, moet je bekend zijn met de term “scope.” Lexical scope is een fancy term voor de huidige omgeving ten opzichte van datgene waar je naar verwijst.

In het volgende voorbeeld wordt de scope van de variabele met de naam myName de “global scope” genoemd.

// global scopeconst myName = "John Doe"function displayName() { // local/function scope console.log(myName);};displayName()

Je hebt dit concept misschien al gezien toen je las over hoe var niet block-scoped is en hoe constlet dat wel is. Het is belangrijk op te merken dat in JavaScript, een functie altijd zijn eigen bereik creëert. Dit wordt de local of function scope genoemd, zoals te zien is in het codevoorbeeld.

Als je goed hebt opgelet, denk je misschien dat myName en displayName onderdeel zijn van een closure. En dan heb je gelijk! Maar omdat de functie en de variabele hier in het globale bereik bestaan, heeft het niet veel zin om het een closure te noemen.

Er zijn veel soorten scopes in JavaScript, maar als het op closures aankomt, zijn er drie scopes die je moet kennen:

  1. Het globale bereik is het standaard bereik waar iedereen in woont. Zie het als je straat
  2. De outer function scope is de functie die een functie retourneert. Het heeft zijn eigen bereik. Zie het als je tuin
  3. De binnenste/lokale functie scope is de teruggegeven functie die een sluiting wordt. Zie het als je huis

Nu duiken we in een aantal use-cases.

Common use-cases voor closures

Currying

Function currying is een ander krachtig concept in functioneel programmeren. Om een curried functie in JavaScript te implementeren, zou je closures gebruiken.

Currying van een functie kan worden beschreven als het transformeren van een functie en wordt als volgt uitgevoerd: add(1, 2, 3) naar add(1)(2)(3).

function add(a) { return function(b) { return function(c) { return a + b + c; }; };};add(1)(2)(3) // returns 6

De add functie neemt een enkel argument en geeft dan twee functies terug die achter elkaar genest zijn. Het doel van currying is om een heleboel argumenten te nemen en uiteindelijk te eindigen met een enkele waarde.

Hogere-orde functies

Het doel van een hogere-orde functie is om een functie als argument te nemen en een resultaat terug te geven. Array-methoden zoals map en reduce zijn voorbeelden van hogere-orde functies.

const arrayOfNumbers = ;const displayNumber = (num) => { console.log(num);}arrayOfNumbers.forEach(displayNumber)

De Array.prototype.forEach hogere-orde functie hier accepteert displayNumber als argument en voert het vervolgens uit voor elk element in de arrayOfNumbers. Als je een UI-framework zoals Vue of React hebt gebruikt, ben je misschien bekend met componenten van hogere orde, die in wezen hetzelfde zijn als functies van hogere orde.

Wat is nu het verschil tussen functies van hogere orde en currying? Terwijl een hogere-orde functie een functie als argument neemt en een waarde retourneert, retourneert een curried functie een functie als resultaat, wat uiteindelijk tot een waarde leidt.

DOM element managers

Dit is een veelgebruikt ontwerppatroon dat vaak wordt gebruikt om eigenschappen van DOM-elementen te krijgen en in te stellen. In het volgende voorbeeld maken we een element manager om elementen te stijlen.

makeStyleManager retourneert een object dat toegang geeft tot twee functies, die deel uitmaken van een closure naast de element en currentStyles variabelen. Zelfs nadat makeStyleManager klaar is met uitvoeren, hebben de getStyle en setStyle functies toegang tot de variabelen.

Conclusie

JavaScript closures kunnen moeilijk te begrijpen zijn, zelfs voor ontwikkelaars met professionele ervaring in hun bagage. Inzicht in closures maakt je uiteindelijk een betere ontwikkelaar.

Je zou nu in staat moeten zijn om een closure te herkennen wanneer die wordt gebruikt in een codebase die er vreemd uitziet of nergens op slaat. Closures zijn een cruciaal concept in functioneel programmeren en ik hoop dat deze gids je heeft geholpen een stap voorwaarts te zetten op je weg om het onder de knie te krijgen.

LogRocket: JavaScript-fouten eenvoudiger debuggen door de context te begrijpen

Het debuggen van code is altijd een vervelende taak. Maar hoe beter u uw fouten begrijpt, hoe gemakkelijker het is om ze op te lossen.

LogRocket stelt u in staat deze fouten op nieuwe en unieke manieren te begrijpen. Onze frontend-monitoringoplossing volgt de betrokkenheid van gebruikers bij uw JavaScript-frontends, zodat u precies kunt achterhalen wat de gebruiker heeft gedaan dat tot een fout heeft geleid.

LogRocket registreert console-logs, paginalaadtijden, stacktraces, langzame netwerkverzoeken/reacties met headers + bodies, browsermetagegevens en aangepaste logboeken. Inzicht in de impact van je JavaScript-code is nog nooit zo eenvoudig geweest!

Probeer het gratis.

Verder lezen

  • “Ik heb JavaScript closures nooit begrepen” – Een diepgaande, technische gids om te begrijpen hoe een closure werkt. Ideaal voor iemand die closures wil begrijpen met betrekking tot de ExecutionContext, call stack, lexicale omgeving, etc.
  • MDN reference for JavaScript closures – Een snelle referentiegids voor closures (inclusief enkele veelvoorkomende valkuilen) voor het geval je je geheugen snel moet bijspijkeren
  • “Master the JavaScript Interview: Wat is een afsluiting? – Closures uitgelegd door Eric Elliot; zeer geschikt voor ontwikkelaars met een goed begrip van functionele programmeerconcepten

Laat een antwoord achter

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