發現一道有意思的面試題:如何實現 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)
。