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.