Los cierres son geniales para la lógica asincrónica.
Se trata principalmente de la organización del código para mí. Tener un montón de funciones locales para dividir lo que está haciendo el código es bueno.
create: function _create(post, cb) {
// cache the object reference
var that = this;
function handleAll(err, data) {
var rows = data.rows;
var id = rows.reduce(function(memo, item) {
var id = +item.id.split(":")[1];
return id > memo ? id : memo;
}, 0);
id++;
var obj = {
title: post.title,
content: post.content,
id: id,
// refer to the object through the closure
_id: that.prefix + id,
datetime: Date.now(),
type: "post"
}
PostModel.insert(obj, handleInsert);
}
// this function doesn't use the closure at all.
function handleInsert(err, post) {
PostModel.get(post.id, handleGet);
}
// this function references cb and that from the closure
function handleGet(err, post) {
cb(null, that.make(post));
}
PostModel.all(handleAll);
}
Aquí hay otro ejemplo de cierre
var cachedRead = (function() {
// bind cache variable to the readFile function
var cache = {};
function readFile(name, cb) {
// reference cache
var file = cache[name];
if (file) {
return cb(null, file);
}
fs.readFile(name, function(err, file) {
if (file) cache[name] = file;
cb.apply(this, arguments);
});
}
return readFile;
})();
Y otro ejemplo
create: function _create(uri, cb, sync) {
// close over count
var count = 3;
// next only fires cb if called three times
function next() {
count--;
// close over cb
count === 0 && cb(null);
}
// close over cb and next
function errorHandler(err, func) {
err ? cb(err) : next();
}
// close over cb and next
function swallowFileDoesNotExist(err, func) {
if (err && err.message.indexOf("No such file") === -1) {
return cb(err);
}
next();
}
this.createJavaScript(uri, swallowFileDoesNotExist, sync)
this.createDocumentFragment(uri, errorHandler, sync);
this.createCSS(uri, swallowFileDoesNotExist, sync);
},
La alternativa al uso de cierres es curvar variables en funciones usando f.bind(null, curriedVariable)
.
Sin embargo, en general, la lógica de programación asincrónica utiliza devoluciones de llamada y el estado de manipulación en las devoluciones de llamada depende del currículum o los cierres. Personalmente prefiero los cierres.
En cuanto a los usos de la herencia prototípica, ¿permite OO? ¿La herencia prototípica realmente necesita hacer más que eso para que se considere "útil"? Es una herramienta de herencia, permite la herencia, eso es lo suficientemente útil.