junlin
junlin

Reputation: 2035

js currying function example

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);

Upvotes: 0

Views: 230

Answers (1)

Gilad Artzi
Gilad Artzi

Reputation: 3084

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 with 1. 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

Upvotes: 1

Related Questions