被一道面试题目难到了。
有函数multi(2)(3)(4)=24,算法是2X3X4=24。
求解multi函数。
求大神解答~
------------------分割线---------------------
最终采纳了@Ende93 的答案,感觉更优美一些。但是代码需要调整一下:
function multi(n){
var fn = function(x) {
return multi(n * x);
};
fn.toString = function() {
return n;
};
return fn;
}
demo: http://jsfiddle.net/etianqq/7sjo4nwt/
------------------分割线---------------------
谢谢 @kikong 的comments,我之前想法是仓促些,之所以demo里面显示为24,是因为dom操作时自动调用了function.toString(),所以显示为数字了。
如果直接console.log(multi(2)(3)(4))--->function... ,如果是console.log(multi(2)(3)(4)+1)--->25.
所以,上面的方案还是有所欠缺的。
首先返回值要是函数,其次要传递值:
上诉代码来自于:codewar 加法链 Best Practices
这不就是函数柯里化嘛。
最简单的方式是定义一个正常的函数,然后用lodash或underscore或者其他类似库完成柯里化。方法如下:
需要注意的是,柯里化需要指定总参数个数,在lodash中如果未指定则视为this.length,在上例中也就是3.
柯里化后的函数将在连续调用n次后返回所需的结果,n为刚刚说的参数个数。
当然,你也可以不用柯里化的方式,直接按对方的逻辑要求用递归简单的实现一下。。
你指的是这样么?
var baseFun = function(a, b, c){
return a b c;
}
var multi = _.curry(baseFun);
console.log(multi(2)(3)(4));
函数curry化,提供一个类似的思路:
函数Curry(柯里)化(部分传参,返回一个已传部分参数的函数;适用于公用一个函数,且传给改函数的部分参数是相同的情况)
function curry (fn) {
var slice = Array.prototype.slice,
old_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = old_args.concat(new_args);
return fn.apply(null, args);
}
}
var add = function (x, y, z) {
return x+y+z;
}
//一步curry化
curry(add, 1)(2, 3); //返回6
//两步curry化
var addOne = curry(add, 1);
var addTwo = curry(addOne, 2);
addTwo(3); //返回6
实现1:)
实现2:要多调用一次,可能和题目的要求不符,但提供了一种可以更多参数调用的可能,参考下
http://roshanca.com/2012/javascript-tiny-quiz/