面接問題:関数コリー化


タイトル
面白い面接問題を発見しました:どのようにadd(1)(2)(3)=6を実現しますか?
まず簡単に分析すると,これは関数伝達値return3 6であることが分かった.
単純な実装
function add(a) {
    return function (b) {
        return function (c) {
            return a + b + c;
        }
    }
}

閉パケットを使用してadd関数を実行すると、最終的に結果を返すために匿名関数がreturnされます.
もちろん,この方法には明らかな欠陥があり,関数がadd(1)(2)(3)(4)になると,我々はまた手動で層をネストしなければならない.
ぶんせき
何か方法はありませんか.あります!
まずこの問題を簡略化します.add()()()など、関数自体の呼び出しをどのように実現しますか.
function add () {
    //   1:  apply
    return function () {
        return add.apply();
    }
    //   2:
    // return add;
}

では、問題はこのように実現できます.
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()は関数を返すので、加算しても値は得られません.
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)もサポートされている.