Javascript Array methods such as forEach
have a thisArg
parameter, which is used as the context for invoking the callback:
array.forEach(callback[, thisArg])
as do every
, some
, filter
and map
. However, reduce
and reduceRight
have no such parameter. Is there some particular reason for this, or some reason it is not necessary?
For instance, consider the following implementation of functional composition using 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];
};
}
I would like to make this "this-aware", so the functions being composed are called in the context in which the function returned by compose
is invoked. Currently they appear to be invoked in the context of the global object. I could do the old var self=this;
at the top of function result
, and use that as the first argument to the cur.apply
call, where I currently have this
, but that would be unnecessary if reduce
took a thisArg
argument.
Am I missing something here, and is there something about reduce
that makes this unnecessary or unuseful?
UPDATE
@kangax Yes, that occurred to me. Far be it from me to criticize the design of the API, but the signature for reduce
seems a bit strange to me. The second optional argument functions differently than normal optional arguments, which typically just have a default value; instead its presence or absence changes the behavior, essentially overloading the function based on signature (argument count). When the second parameter is absent, the first element of the array becomes the starting value and the first call to the callback is against the second value. It seems to me that this behavior could be easily emulated by simply calling
array.slice(1).reduce(fn,array[0])
instead of building in special rules for the case where the second argument is omitted, which in turn, if your presumption is correct, also made it essentially impossible to figure out where to specify the thisArg
argument. Then again, I am sure such issues were already debated while the spec was being hashed out, and there may be good reasons for such an approach.