Douglas Crockford の著書 "Javascript: The Good Parts" で、彼はcurry
関数と引数を受け取り、その関数に既に追加された引数を返すメソッドのコードを提供しています (明らかに、これは実際には「カレー」が意味するものではなく、「部分適用」)。これは、彼が作成した他のカスタム コードがなくても機能するように変更したコードです。
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
すでに引数が 1 つある新しい関数を作成できます。
var add1 = add.curry(1);
add1(2); // returns 3
それはうまくいきます。しかし、私が知りたいのは、なぜ彼が に設定this
したの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)));
};
};
例
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"
Douglas Crockford のやり方でやろうとすると、次のようになります。
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"
しかし、ダグラス・クロックフォードが自分のやり方でやったのなら、おそらく正当な理由があると思います。私は何が欠けていますか?