Методы Javascript Array, такие как forEach
, имеют параметр thisArg
, который используется как контекст для вызова обратного вызова:
array.forEach(callback[, thisArg])
как и every
, some
, filter
и map
. Однако reduce
и reduceRight
не имеют такого параметра. Есть ли какая-то особая причина для этого, или почему-то это не нужно?
Например, рассмотрим следующую реализацию функционального состава, используя reduceRight
:
function compose () {
var fns = [].slice.call(arguments,0);
return function result() {
return fns.reduceRight(
function (prev,cur){
return [cur.apply(this,prev)];
},
arguments
)[0];
};
}
Я хотел бы сделать это "this-aware", поэтому выполняемые функции вызывают в контексте, в котором вызывается функция, возвращаемая compose
. В настоящее время они, похоже, вызывается в контексте глобального объекта. Я мог бы сделать старый var self=this;
в верхней части функции result
и использовать это как первый аргумент для вызова cur.apply
, где у меня в настоящее время есть this
, но это было бы необязательно, если reduce
взял thisArg
.
Мне что-то не хватает, и есть ли что-то о reduce
, что делает это ненужным или непонятным?
UPDATE
@kangax Да, это произошло со мной. Далеко от меня критиковать дизайн API, но подпись для reduce
кажется мне немного странной. Второй необязательный аргумент функционирует иначе, чем обычные необязательные аргументы, которые обычно имеют значение по умолчанию; вместо этого его присутствие или отсутствие изменяет поведение, существенно перегружая функцию, основанную на сигнатуре (счет аргумента). Когда второй параметр отсутствует, первый элемент массива становится стартовым, а первый вызов обратного вызова относится к второму значению. Мне кажется, что это поведение можно легко эмулировать, просто называя
array.slice(1).reduce(fn,array[0])
вместо создания в специальных правилах для случая, когда второй аргумент опущен, что, в свою очередь, если ваша презумпция верна, также существенно не определило, где указать аргумент thisArg
. Опять же, я уверен, что такие вопросы уже обсуждались, пока спецификация была хэширована, и могут быть веские причины для такого подхода.