JavaScript curry / schönfinkeln
JavaScript curry / schönfinkeln
假设我声明了以下函数
function curry(fn) {
var args = [];
// push everything but function itself into args
for (var i = 1; i < arguments.length; ++i) {
args.push(arguments[i]);
}
return function() {
var args2 = [];
for (var i = 0; i < arguments.length; i++) {
args2.push(arguments[i]);
}
var argstotal = args.concat(args2);
return fn.apply(argstotal);
};
}
function add(a,b){return a + b};
我想做的是显而易见的,我想curry add函数,它本身工作得很好
var addCurry = curry(add);
addCurry(10, 20, 12314) // should deliver 30, gives NaN
不知怎么的,它返回NaN,我不知道我做错了什么…有人知道吗?
这里有一个差一的错误:return fn.apply(argstotal)
Function.prototype.apply
的第一个参数是一个作用域,this
在调用中的值,不是第一个参数。如果要从您的curry函数中打印出arguments
,您将看到:
function curry(fn) {
var args = [];
// push everything but function itself into args
for (var i = 1; i < arguments.length; ++i) {
args.push(arguments[i]);
}
return function() {
var args2 = [];
for (var i = 0; i < arguments.length; i++) {
args2.push(arguments[i]);
}
var argstotal = args.concat(args2);
return fn.apply(argstotal);
};
}
function add(a, b) {
console.log('debug', this, arguments);
return a + b;
}
var cadd = curry(add, 1);
cadd(2);
你可以很容易地用两种方法修复这个问题:
- 将
this
传递给柯里化函数 - 忽略
this
,不为柯里函数设置
第一个选项可能更好,因为它不会让开发人员感到惊讶。你可以使用:
function curry(fn) {
var args = [];
// push everything but function itself into args
for (var i = 1; i < arguments.length; ++i) {
args.push(arguments[i]);
}
return function() {
var args2 = [];
for (var i = 0; i < arguments.length; i++) {
args2.push(arguments[i]);
}
var argstotal = args.concat(args2);
return fn.apply(this, argstotal); // <-- only change
};
}
function add(a, b) {
console.log('debug', /* this, */ arguments);
return a + b;
}
var cadd = curry(add, 1);
cadd(2);
第二个选项可以通过fn.apply(null, argstotal)
实现