问题
How to understand the currying
function?
How the newSum
and newFind
works?
var currying = function(fn) {
var args = [];
return function() {
if (!!arguments.length) {
[].push.apply(args, arguments); // What's the meaning of this writing?
return arguments.callee;
} else {
return fn.apply(this, args);
}
}
}
// accumulation currying
var sum = (function(num){
var ret = 0;
return function(){
for(var i = 0, len = arguments.length; i < len; i++) {
ret += arguments[i];
}
return ret;
}
})();
var newSum = currying(sum);
newSum(1)(2)(3)(4)() // 10
// element find currying
var find = function(arr, el){
return arr.indexOf(el) !== -1;
}
var newFind = currying(find)([1,2,3]);
newFind(1);
newFind(2);
回答1:
The currying
function, and gets a function as an argument, and returns a new function, that when invoked:
- If arguments are provided, they are accumulated in the
args
array - If arguments are not provided, the original function is called with all accumulated arguments.
So, if we look at this call for example: newSum(1)(2)(3)(4)()
- there are 5 function invocations:
- Calling
newSum
with1
. Getting the curried function with 1 accumulated. - Calling the curried function with 2 - getting the same function with 1 and 2 accumulated, and so on for 3 and 4.
- Calling the curried function without arguments - applying all the accumulated arguments (1, 2, 3, 4) to the original
sum
function - and getting the correct value, 10.
About [].push.apply(args, arguments);
and fn.apply(this, args);
: apply
is a method on Function.prototype
that basically lets you call a function, supplying a context object and an array of arguments. So basically [].push.apply(...)
is a trick of concatenating an array into another array, in our case, concat arguments
(which is the list of arguments provided to a function upon invocation) into args
(the accumulating list of arguments). fn.apply(this, args);
is simply calling the original function with all the accumulated arguments. You can read more about it in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
By the way, newFind(1);
and newFind(2);
both return a function, that will look for the index of the element only when invoked, meaning newFind(1)() === true
来源:https://stackoverflow.com/questions/46745206/js-currying-function-example