在 Douglas Crockford 的书《Javascript:The Good Parts》中,他提供了curry
方法接受一个函数和参数并返回已添加参数的函数(显然,这并不是真正的"咖喱"是什么意思 https://stackoverflow.com/tags/currying/info,但是是一个例子“部分应用” https://stackoverflow.com/tags/partial-application/info)。这是代码,我对其进行了修改,以便无需他编写的其他自定义代码即可运行:
Function.prototype.curry = function(){
var slice = Array.prototype.slice,
args = slice.apply(arguments),
that = this;
return function() {
// context set to null, which will cause `this` to refer to the window
return that.apply(null, args.concat(slice.apply(arguments)));
};
};
所以如果你有一个add
功能:
var add = function(num1, num2) {
return num1 + num2;
};
add(2, 4); // returns 6
您可以创建一个已有一个参数的新函数:
var add1 = add.curry(1);
add1(2); // returns 3
效果很好。但我想知道的是他为什么要设置this
to null
?柯里化方法是否与原始方法相同(包括相同的内容)不是预期的行为吗?this
?
我的咖喱版本看起来像这样:
Function.prototype.myCurry = function(){
var slice = [].slice,
args = slice.apply(arguments),
that = this;
return function() {
// context set to whatever `this` is when myCurry is called
return that.apply(this, args.concat(slice.apply(arguments)));
};
};
Example
(这是示例的jsfiddle) http://jsfiddle.net/38z2r/5/
var calculator = {
history: [],
multiply: function(num1, num2){
this.history = this.history.concat([num1 + " * " + num2]);
return num1 * num2;
},
back: function(){
return this.history.pop();
}
};
var myCalc = Object.create(calculator);
myCalc.multiply(2, 3); // returns 6
myCalc.back(); // returns "2 * 3"
如果我尝试按照道格拉斯·克罗克福德的方式去做:
myCalc.multiplyPi = myCalc.multiply.curry(Math.PI);
myCalc.multiplyPi(1); // TypeError: Cannot call method 'concat' of undefined
如果我按照自己的方式去做:
myCalc.multiplyPi = myCalc.multiply.myCurry(Math.PI);
myCalc.multiplyPi(1); // returns 3.141592653589793
myCalc.back(); // returns "3.141592653589793 * 1"
然而,我觉得如果道格拉斯·克罗克福德按照他的方式这样做,他可能有充分的理由。我缺少什么?