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


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

(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)的解決方案(閉包實現)

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)的解決方案

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;
        }
    }
}

二、函數柯里化的思路

通俗的理解,由於函數柯里化具有這樣的特性:它能夠"積累"函數的參數(不管是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)的解決方案:

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):

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;
}

 

完!

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM