面試題:函數柯里化

題目

發現一道有意思的面試題:如何實現 add(1)(2)(3)=6javascript

首先簡單分析一下,咱們就能發現這是一個函數傳值 return3次獲得6java

簡單實現

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 方法。
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)

相關文章
相關標籤/搜索