Un esempio comporta una chiusura, l'altro no. L'implementazione delle chiusure è piuttosto complicata, dal momento che le variabili chiuse non funzionano come le normali variabili. Questo è più ovvio in un linguaggio di basso livello come C, ma userò JavaScript per illustrarlo.
Una chiusura non consiste solo di una funzione, ma anche di tutte le variabili su cui ha chiuso. Quando vogliamo invocare tale funzione, dobbiamo anche fornire tutte le variabili chiuse. Possiamo modellare una chiusura mediante una funzione che riceve un oggetto come primo argomento che rappresenta queste variabili chiuse:
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 chiamata imbarazzante che closure.apply(closure, ...realArgs)
richiede
Il supporto per gli oggetti incorporati di JavaScript consente di omettere l' vars
argomento esplicito e ci consente this
invece di utilizzare :
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 usando 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 quest'ultimo esempio, l'oggetto viene utilizzato solo per raggruppare le due funzioni restituite; l' this
associazione è irrilevante. Tutti i dettagli su come rendere possibili le chiusure - passando i dati nascosti alla funzione reale, cambiando tutti gli accessi alle variabili di chiusura alle ricerche in quei dati nascosti - sono curati dalla lingua.
Ma chiamare le chiusure comporta l'overhead del passaggio di quei dati extra, e l'esecuzione di una chiusura comporta l'overhead delle ricerche in quei dati extra - aggravati dalla cattiva localizzazione della cache e di solito una dereferenza del puntatore rispetto alle variabili ordinarie - quindi non sorprende che una soluzione che non si basa su chiusure funziona meglio. Soprattutto perché tutto ciò che la tua chiusura ti salva da fare sono alcune operazioni aritmetiche estremamente economiche, che potrebbero anche essere piegate costantemente durante l'analisi.