Os fechamentos são ótimos para lógica assíncrona.
É principalmente sobre organização de código para mim. É bom ter várias funções locais para dividir o que o código está fazendo.
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);
}
Aqui está outro exemplo de fechamento
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;
})();
E outro exemplo
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);
},
A alternativa ao uso de fechamentos é transformar a variável em funções usando f.bind(null, curriedVariable)
.
Geralmente, porém, a lógica de programação assíncrona usa retornos de chamada e o estado de manipulação nos retornos de chamada depende de currying ou fechamento. pessoalmente eu prefiro fechamentos.
Quanto aos usos de herança prototípica, permite OO? A herança prototípica realmente precisa fazer mais do que isso para ser considerada "útil". É uma ferramenta de herança, permite herança, que é útil o suficiente.