Использую Backbone в связке с Rivets.js для data-bind (Весит ~3Кб). Очень хорошо себя показал на гигантских формах с кучей вложенных многоуровневых коллекций. Плюс ко всему Rivets можно адаптировать под любое хранилище данных, хоть под простой JavaScript объект. Рекомендую посмотреть ;-)
Поддерживаю оба мнения. Еще о блоках в JavaScript многие просто не знают и при виде
MyBlock: {
console.log('This is MyBlock');
}
возникнет вопрос «эээ что это??? а так можно?» и человеку придется разбираться. Сегодня как правило, во всех ЯП большие блоки «именуют» путем выноса в отдельную функцию. Вы же не пишете код для себя ;-)
Во многих виртуальных машинах JavaScript к функции при ее инициализации добавляется специальный объект Scope, который описывает область видимости функции и чаще всего он инициализируется сразу же — в него попадают ссылки на все переменные контекстов до которых может достучаться функция. Если переменных много и контекст многоуровневый и функции генерируются очень часто (типичный функциональный подход), то это дорого. Полюс ко всему JIT компилятору нужно каждый раз оптимизировать каждую функцию.
Методы прототипа инициализируются только один раз и делегируют свое использование инстансу.
Не разработчик, но расскажу:
Самая дорогая операция — nextTick, но тут все Promise/A+ равны. Поэтому даже самый плохой Promise/A будет быстрее любого Promise/A+ в синтетических тестах
Q — адов функциональный кошмар, генерация функций вместо использования прототипов — долго, не оптимально, затратно по памяти
Vow — чистые прототипы, нет генераций функций. Поэтому предельно дешево, JIT-friendly. Но нужно немного допилить, чтобы было совсем хорошо.
Еще есть один важный хэлпер — Q.nfbind и Q.nfapply, Q.nfcall с ним. С ним можно просто сделать вот:
var readFile = Q.nfbind(fs.readFile);
Понятно, что есть vow-fs, но nfbind нужен не только для fs.
Еще есть достаточно частый кейс, когда разработчик ожадает, что функции resolve и reject забиндены к контексту при рождении. И можно делать вот так:
var timeout = function (ms) {
var dfd = $.Deferred();
setTimeout(dfd.resolve, ms);
return dfd.promise();
};
// VS
var timeout = function (ms) {
var promise = Vow.promise();
// .bind :(
setTimeout(promise.fulfill.bind(promise), ms);
return promise;
};
Понятно, что vow выигрывает на экономии в бинде, но это уродует код.
Эффективнее это будет сделать на RiverTrail aka Parallel.js (вычисления на GPU) который, кстати, уже включен в FF Nighty. И, как ни странно, имеет обратную совместимость c однопоточным и процессорным JavaScript.
asm.js имеет очень ограниченный user-case и хорош только для написания молотилок цифр. Для многих их нас от него не будет ни горячо ни холодно. Однако же используя AOT компиляцию это даст существенный прирост в скорости рассчета физики в играх, адовы алгоритмы вроде Дугласа-Пекера и вычисление любого хэша. Притом, что функция, написанная, с asm.js будет работать быстрее из-за строгой типизации на бинарном уровне в любом браузере. В итоге выигрывают все!
возникнет вопрос «эээ что это??? а так можно?» и человеку придется разбираться. Сегодня как правило, во всех ЯП большие блоки «именуют» путем выноса в отдельную функцию. Вы же не пишете код для себя ;-)
Методы прототипа инициализируются только один раз и делегируют свое использование инстансу.
Самая дорогая операция — nextTick, но тут все Promise/A+ равны. Поэтому даже самый плохой Promise/A будет быстрее любого Promise/A+ в синтетических тестах
Q — адов функциональный кошмар, генерация функций вместо использования прототипов — долго, не оптимально, затратно по памяти
Vow — чистые прототипы, нет генераций функций. Поэтому предельно дешево, JIT-friendly. Но нужно немного допилить, чтобы было совсем хорошо.
Еще есть один важный хэлпер — Q.nfbind и Q.nfapply, Q.nfcall с ним. С ним можно просто сделать вот:
Понятно, что есть vow-fs, но nfbind нужен не только для fs.
Еще есть достаточно частый кейс, когда разработчик ожадает, что функции resolve и reject забиндены к контексту при рождении. И можно делать вот так:
Понятно, что vow выигрывает на экономии в бинде, но это уродует код.