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功能正在执行什么。
答案 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
函数。