Un esempio comporta una chiusura, l'altro no. L'implementazione delle chiusure è piuttosto complicata, poiché le variabili chiuse su non funzionano come le variabili normali. Questo è più ovvio in un linguaggio di basso livello come C, ma userò JavaScript per illustrarlo.
Una chiusura non consiste solo in una funzione, ma anche in tutte le variabili su cui si è chiusa. Quando vogliamo invocare questa funzione, dobbiamo anche fornire tutte le variabili chiuse. Possiamo modellare una chiusura con una funzione che riceve un oggetto come primo argomento che rappresenta queste variabili chiuse sopra:
function add(vars, y) {
vars.x += y;
}
function getSum(vars) {
return vars.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(adder, 2);
console.log(adder.getSum(adder)); //=> 42
Nota la convenzione di chiamate awkward closure.apply(closure, ...realArgs)
che richiede
Il supporto per oggetti incorporati di JavaScript rende possibile omettere l'argomento vars
esplicito e ci consente invece di utilizzare this
invece:
function add(y) {
this.x += y;
}
function getSum() {
return this.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
Questi esempi sono equivalenti a questo codice che utilizza effettivamente le chiusure:
function makeAdder(x) {
return {
add: function (y) { x += y },
getSum: function () { return x },
};
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
In questo ultimo esempio, l'oggetto è usato solo per raggruppare le due funzioni restituite; il binding di this
è irrilevante. Tutti i dettagli per rendere possibili le chiusure - passando i dati nascosti alla funzione reale, cambiando tutti gli accessi alle variabili di chiusura per le ricerche in quei dati nascosti - sono curati dal linguaggio.
Ma chiamare le chiusure implica il sovraccarico di passare quei dati in più, e l'esecuzione di una chiusura comporta il sovraccarico delle ricerche in quei dati extra - aggravata dalla cattiva localizzazione della cache e di solito una dereferenziazione del puntatore rispetto alle variabili ordinarie - così che sia non sorprende che una soluzione che non si basa su chiusure funzioni meglio. Tanto più che tutto ciò che la tua chiusura ti fa risparmiare è un paio di operazioni aritmetiche estremamente economiche, che potrebbero persino essere piegate in modo costante durante l'analisi.