Шрифт:
// передает все свои аргументы функции g, затем передает значение, полученное от g,
// функции f и возвращает результат вызова f. Обе функции, f и g,
// вызываются с тем же значением this, что и h.
function compose(f,g) {
return function {
// Для вызова f используется call, потому что ей передается
// единственное значение, а для вызова g используется apply,
// потому что ей передается массив значений,
return f.call(this, g.apply(this, arguments));
};
}
var square = function(x) { return x*x; };
var sum = function(x,y) { return x+y; };
var squareofsum = compose(square, sum);
squareofsum(2,3) // => 25
Функции
partial
и memoize,
которые определяются в следующем разделе, представляют собой еще две важные функции высшего порядка. 8.8.3. Частичное применение функций
Метод
bind
функции f (раздел 8.7.4) возвращает новую функцию, которая вызывает f в указанном контексте и с заданным набором аргументов. Можно сказать, что он связывает функцию с объектом контекста и частично применяет аргументы. Метод bind
применяет аргументы слева, т.е. аргументы, которые передаются методу bind,
помещаются в начало списка аргументов, передаваемых оригинальной функции. Однако есть возможность частичного применения аргументов справа:
// Вспомогательная функция преобразования объекта (или его части),
// подобного массиву, в настоящий массив. Используется ниже
// для преобразования объекта arguments в настоящий массив,
function array(a, n) { return Array.prototype.slice.call(a, n || 0); }
// Аргументы этой функции помещаются в начало списка
function partialLeft(f /*, ...*/) {
var args = arguments; // Сохранить внешний массив аргументов
return function { // И вернуть эту функцию
var а = array(args, 1); // Начиная с элемента 1 во внеш. масс,
а = a.concat(array(arguments)); // Добавить внутренний массив аргум.
return f.apply(this, а); // Вызвать f с этим списком аргументов
};
}
// Аргументы этой функции помещаются в конец списка
function partialRight(f /*, ...*/) {
var args = arguments; // Сохранить внешний массив аргументов
return function { // И вернуть эту функцию
var а = array(arguments); // Начинать с внутр. масс, аргументов
а = a.concat(array(args,1)); // Добавить внешние арг., начиная с 1.
return f.apply(this, а); // Вызвать f с этим списком аргументов
};
}
// Аргументы этой функции играют роль шаблона. Неопределенные значения
// в списке аргументов заполняются значениями из внутреннего набора,
function partial(f /*, ... */) {
var args = arguments; // Сохранить внешний массив аргументов
return function {
var a = array(args, 1); // Начинать с внешнего массива аргументов
var i=0, j=0;
// Цикл по этим аргументам, заменить значения undefined значениями