一道javascript面試題(閉包與函數柯里化)

要求寫一個函數add(),分別實現能以下效果:html

(1)console.log(add(1)(2)(3)(4)());//10
(2)console.log(add(1,2)(3,4)());//10
(3)console.log(add(1,2)(3,4));//10

針對(1)和(2),有兩種思路實現:純閉包思路和函數柯里化思路。數組

1、閉包思路

(1)的解決方案(閉包實現)閉包

function add(arg) {
    // body...
    let sum = 0;
    sum+=arg;
    return  function (tmarg) {
        // body...
        if (arguments.length == 0) {
            return sum;
        }else{
            sum+=tmarg;
            return arguments.callee;
        }
    }
}

(2)的解決方案app

function add(arg) {
    // body...
    let sum = 0;
    sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum);
    return  function (tmarg) {
        // body...
        if (arguments.length == 0) {
            return sum;
        }else{
            sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum);
            return arguments.callee;
        }
    }
}

2、函數柯里化的思路

通俗的理解,因爲函數柯里化具備這樣的特性:它可以"積累"函數的參數(無論是foo(1,2,3)仍是foo(1)(2)(3)這種鏈式形式)),而且延遲執行。能夠將多個參數積累到一個數組中,在最後一步執行求和。
柯里化通用形式:函數

function curry(fn) {
    // body...
    var args = Array.prototype.slice.call(arguments,1);
    return function () {
        // body...
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = args.concat(innerArgs);
        console.log(finalArgs);
        return fn.apply(null,finalArgs);
    };
}

 

(2)的解決方案:spa

function add() {
    let sum = 0;
    var _args = Array.prototype.slice.call(arguments);    
    var tmpf = function(){ 
        if(arguments.length === 0) { 
            sum = _args.reduce((a,b) => {return a + b;},sum);
        }   
        _args.push.apply(_args,[].slice.call(arguments));
        return tmpf;
    }
} 

 

針對問題(3):prototype

function add(arg) {
    // body...
    let sum = 0;
    sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum);
    var tmpf = function (tmarg) {
        // body...
        if (arguments.length == 0) {
            return sum;
        }else{
            sum = Array.prototype.slice.call(arguments).reduce((a,b) => {return a+b;},sum);
            return tmpf;
        }
    };
    tmpf.toString = tmpf.valueOf = function () {
        // body...
        return sum;
    }
    return tmpf;
}

 

完!code

轉載請註明原文出處:http://www.cnblogs.com/qcblog/p/6858947.htmlhtm

相關文章
相關標籤/搜索