Как же нам реализовать compose?
По частям. Для начала создадим синонимы, чтобы не писать много кода.
var callGetSummary = func("getSummary");
var getText = prop("text");
var summarize = compose([p, getText, callGetSummary]);
Все просто и очевидно. Едем дальше. Разберем, что же происходит, когда мы вызываем функцию summarize.
Шаг первый
var callGetSummary = func("getSummary");
var getText = prop("text");
var summarize = compose([p, getText, callGetSummary]);
// summarize(obj);
// => callGetSummary(obj)
Объект предеается в последнюю функцию из списка, а именно getSummary. Она возвращает нам объект типаsummary. А этот объект передается в следующую функцию, getText
Шаг второй
var callGetSummary = func("getSummary");
var getText = prop("text");
var summarize = compose([p, getText, callGetSummary]);
// summarize(obj);
// => getText(callGetSummary(obj))
В результате второго шага мы получим строку, которая содержится в свойстве text. А после этого строка попадет в функцию, которая создаст нам DOM объект p.
Шаг третий
var callGetSummary = func("getSummary");
var getText = prop("text");
var summarize = compose([p, getText, callGetSummary]);
// summarize(obj);
// => p(getText(callGetSummary(obj)))
Это пример простой композиции, когда параметр передается из функцию в функцию последовательно. Можно создать композицию, когда параметр будет передаваться в каждую функцию, и на выходе будет список результатов. Или еще как-то.
Итак, вернемся к нашему многострадальному примеру.
builSummary: function() {
var summarize = compose(
[p, prop("text"), func("getSummary")]);
return div(this.components.map(summarize));
}
Сначала мы создали функцию вычисления результатов. А потом применили map.
При этом заметьте, что функция summarize абсолютно не знает, с каким объектом она работает. Это три различных абстракции, которые соединяются исключительно благодаря функции compose. Поэтому мы можем вынести summarize в отдельную сущность.
var summarize = compose(
[p, prop("text"), func("getSummary")]);
// ...
builSummary: function() {
return div(this.components.map(summarize));
}
Выглядит здорово и красиво, но что насчет производительности?