Closure
In de informatica is een closure een functie die gebruikmaakt van variabelen die zich bevinden in het bereik waarin de functie is gedefinieerd, maar niet per se in het bereik waarin de functie wordt aangeroepen.
Zulke variabelen van een closure worden samen de omgeving van de closure genoemd.
Veel programmeertalen ondersteunen wel functies, maar geen closures. Ondersteuning voor closures is vooral aanwezig in functionele programmeertalen (zoals Haskell en Ocaml), programmeertalen die sterk gebaseerd zijn op functionele talen (zoals JavaScript) of talen waaraan achteraf functionele elementen zijn toegevoegd (zoals C#).
Voorbeeld in JavaScript
[bewerken | brontekst bewerken]var maakClosure = function (a) {
return function (b) {
return a + b;
};
};
De bovenstaande JavaScript-functie retourneert een closure: de variabele a
behoort tot de omgeving van de geretourneerde functie, maar is buiten de functie maakClosure
niet bekend.
We kunnen deze closures aan variabelen toekennen:
var closure1 = maakClosure(3);
var closure2 = maakClosure(8);
en vervolgens aanroepen als aparte functies:
var x = closure1(4); // x is nu 7
var y = closure2(4); // y is nu 12
De twee functies closure1
en closure2
hebben beide hun eigen versie van de variabele a
. Die maakt deel uit van de omgeving die gemaakt werd toen maakClosure
werd aangeroepen. Ze zijn geen lokale variabelen van de functie zelf, en ook geen globale variabelen.
Privé-variabelen
[bewerken | brontekst bewerken]Met behulp van closures is het mogelijk een functie één of meer privé-variabelen te geven die blijven bestaan tussen de verschillende aanroepen van die functie.
Het volgende voorbeeld in JavaScript kan dit verduidelijken:
var maakClosure = function() {
var a = 0;
return function() {
a++;
return a;
};
};
De functie maakClosure() retourneert weer een closure:
var f = maakClosure();
var g = maakClosure();
De functies f() en g() hebben nu elk een privé-variabele a, die blijft bestaan tussen de aanroepen door:
var x = f(); // x is nu 1
var y = f(); // y is nu 2!
var z = g(); // z is nu 1
var w = f(); // w is nu 3
var v = g(); // v is nu 2
Dit werkt dus anders dan wanneer a
een lokale variabele was (dan zou de waarde tussen aanroepen in niet behouden blijven) en ook anders dan wanneer a
een globale variabele was (dan zouden beide functies dezelfde variabele wijzigen).
De werking is vergelijkbaar met die van objectvariabelen (attributen) in objectgeoriënteerd programmeren - al worden hier functies geïnstantieerd in plaats van objecten. (Overigens zijn in JavaScript functies objecten.)