有人可以帮我理解Javascript中的这段代码吗?

时间:2017-01-17 21:00:07

标签: javascript currying

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."

我可以全面了解正在发生的事情,但我不明白curryIt功能正在执行什么。

2 个答案:

答案 0 :(得分:1)

每个函数都有一个名为arguments的对象,它在数组结构中包含函数的调用者所使用的参数。

例如,让我们有以下功能:

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

如果我们按以下方式致电sum

sum(3,4)

arguments将包含两个项目3和4.(实际上,您可以使用3,4或更多参数调用sum。所有这些值都将包含在参数中。)

上述语句中的关键字数组,如数据结构arguments不是数组。所以你不能使用Array的方法(推,移,切片等)

slice是什么?

  

slice()方法返回数组部分的浅表副本   到从开始到结束选择的新数组对象(不包括结束)。   原始数组不会被修改。

有关详细信息,请查看此处。

  

因此,如果您希望apply上的arguments切片可以吗?

由于arguments不是数组,(arguments instanceof Array返回false),您无法执行以下操作:

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

但你不能像下面这样做:

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

什么叫?

  

call()方法使用给定的值调用函数   论据单独提供。

有关详细信息,请查看here

基本上,以下代码行

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

在传递1的slice个对象上调用名为arguments的函数作为它的参数。所以你得到一个包含除第一个之外的所有参数的数组。

答案 1 :(得分:0)

这就是一个名为Currying的函数式编程范例。它是关于将一​​个或多个参数保存到返回函数中以便稍后重新使用的全部内容。它与JavaScript的闭包主题密切相关。

让我们以更实用的方式重构代码。



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函数接受多个参数,其中第一个是名为uncurried的函数,其余参数在rest args数组中通过rest运算符的帮助收集({ ES6的{1}}。

然后我们返回一个函数,该函数接受一个名为...的参数,并利用name数组传递给它的父函数的参数。所以,现在args数组及其元素正在关闭。返回的函数将通过以适当的顺序提供可用的参数来调用传递的args函数。