Un ejemplo implica un cierre, el otro no. Implementar cierres es un poco complicado, ya que las variables cerradas no funcionan como las variables normales. Esto es más obvio en un lenguaje de bajo nivel como C, pero usaré JavaScript para ilustrar esto.
Un cierre no solo consiste en una función, sino también en todas las variables que cerró. Cuando queremos invocar esa función, también debemos proporcionar todas las variables cerradas. Podemos modelar un cierre por una función que recibe un objeto como primer argumento que representa estas variables cerradas:
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
Tenga en cuenta la convención de llamadas incómodas que closure.apply(closure, ...realArgs)esto requiere
El soporte de objetos incorporados de JavaScript hace posible omitir el varsargumento explícito , y nos permite usar thisen su lugar:
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
Esos ejemplos son equivalentes a este código que en realidad usa cierres:
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
En este último ejemplo, el objeto solo se usa para agrupar las dos funciones devueltas; La thisunión es irrelevante. El lenguaje se ocupa de todos los detalles de hacer posibles los cierres: pasar datos ocultos a la función real, cambiar todos los accesos a las variables de cierre a búsquedas en esos datos ocultos.
Pero llamar a los cierres implica la sobrecarga de pasar esos datos adicionales, y ejecutar un cierre implica la sobrecarga de las búsquedas en esos datos adicionales, empeorado por la mala ubicación de la caché y generalmente una desferencia de puntero en comparación con las variables ordinarias, por lo que no es sorprendente que Una solución que no se basa en cierres funciona mejor. Especialmente porque todo lo que su cierre le ahorra hacer son algunas operaciones aritméticas extremadamente baratas, que incluso podrían doblarse constantemente durante el análisis.