发现一道有意思的面试题:如何实现 add(1)(2)(3)=6
?javascript
首先简单分析一下,咱们就能发现这是一个函数传值 return3次获得6
。java
function add(a) { return function (b) { return function (c) { return a + b + c; } } }
利用闭包,执行add函数时return一个匿名函数,用于最终返回结果。面试
固然,这个方法有个明显缺陷,就是若是函数变成 add(1)(2)(3)(4)
,咱们就又要手动嵌套一层。闭包
有没有什么办法呢? 有!app
咱们先把这个问题简化一下:函数
如何实现函数对自身的调用呢,如: add()()()
?prototype
function add () { // 方法1:利用apply return function () { return add.apply(); } // 方法2: // return add; }
那么,问题就能够这么实现:code
function add () { var args = Array.prototype.slice.call(arguments); console.log(args); var fn = function () { var fn_args = Array.prototype.slice.call(arguments); return add.apply(null, args.concat(fn_args)); }; return fn; }
至此, add
函数的多层嵌套以及全部参数,咱们都拿到了,下面只须要把参数相加就能够了。对象
但咱们不能直接相加,由于咱们 add
函数 return add.apply()
返回的是函数, 所以即便相加,值咱们也是拿不到的。ip
这里咱们要用到 valueOf
方法。
valueOf 方法返回指定对象的原始值。
function add () { var args = Array.prototype.slice.call(arguments); var fn = function () { var fn_args = Array.prototype.slice.call(arguments); return add.apply(null, args.concat(fn_args)); }; fn.valueOf = function () { return args.reduce(function (a, b) { return a + b; }); }; return fn; }
搞定!如今这个方法不只支持 add(1)(2)(3)
并且支持 add(1,2,3)
。