В книге Дугласа Крокфорда "Javascript: Good Parts" он предоставляет код для метода curry
, который принимает функцию и аргументы и возвращает эту функцию с уже добавленными аргументами (по-видимому, это не действительно то, что означает "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
Вы можете создать новую функцию, у которой уже есть один аргумент:
var add1 = add.curry(1);
add1(2); // returns 3
Это прекрасно работает. Но что я хочу знать, почему он установил this
в null
? Не ожидалось ли, что метод curries совпадает с оригиналом, включая тот же 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"
Если я попытаюсь сделать это, Дуглас Крокфорд:
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"
Однако мне кажется, что если Дуглас Крокфорд сделал это по-своему, у него, вероятно, есть веская причина. Что мне не хватает?