-2
var curryIt = function(uncurried) {
  var parameters = Array.prototype.slice.call(arguments, 1);
  return function() {
    return uncurried.apply(this, parameters.concat(
      Array.prototype.slice.call(arguments, 0)
    ));
  };
};
var greeter = function(greeting, separator, emphasis, name) {
  console.log(greeting + separator + name + emphasis);
};
var greetHello = curryIt(greeter, "Hello", ", ", ".");
greetHello("Heidi"); //"Hello, Heidi."
greetHello("Eddie"); //"Hello, Eddie."

I get the overall picture of what is happening but I do not understand what is being carried out in the curryIt function.

Ajayv
  • 374
  • 2
  • 13

2 Answers2

1

Every function has an object called arguments, which contains in an array like data structure the arguments which the caller of the function uses.

For example, let that we have the following function:

function sum(a,b){
    return a+b;
}

If we call sum as below:

sum(3,4)

the arguments would contain two items 3 and 4. (Actually, you could call sum with 3, 4 or more arguments. All these values would be contained in the arguments).

The key word in the above statement is the array like data structure. arguments is not an array. So you can't have available the Array's methods (push, shift, slice, etc.)

What does slice?

The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included). The original array will not be modified.

For further info please have a look here.

So if you want to apply slice on arguments would could you do?

Since arguments is not an array, (arguments instanceof Array returns false), you can't do so like below:

var a = ["zero", "one", "two", "three"];
var sliced = a.slice(1,3);

But you can't do it like below:

Array.prototype.slice.call(arguments, 1);

What does call?

The call() method calls a function with a given this value and arguments provided individually.

For further info please have a look here.

So, essentially, the following line of code

Array.prototype.slice.call(arguments, 1);

calls the function called slice on the arguments objects passing 1 as it's argument. So you get an array with all the arguments except the first.

Christos
  • 53,228
  • 8
  • 76
  • 108
0

This is all about a functional programming paradigm called Currying. It's all about saving one or more arguments into a returned function to be re used at a later time. It's highly related with the closures topic of JavaScript.

Let's refactor the code in a more functional manner.

var curryIt = (uncurried,...args) => name => uncurried(...args,name),
    greeter = (greeting, separator, emphasis, name) => console.log(greeting + separator + name + emphasis),
 greetHello = curryIt(greeter, "Hello", ", ", ".");
 
greetHello("Heidi"); //"Hello, Heidi."
greetHello("Eddie"); //"Hello, Eddie."

curryIt function takes several argument of which the first one is a function called uncurried the rest of the argument are collected in the args array by the help of the rest operator (...) of ES6.

Then we return a function which takes a single argument called name and makes use of the parameters passed to it's parent function by args array. So, right now the args array and it's elements are under closure. The returned function will invoke the passed uncurried function by providing the available arguments in a proper order.

Redu
  • 25,060
  • 6
  • 56
  • 76