zoukankan      html  css  js  c++  java
  • 一道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

  • 相关阅读:
    Java 并发理论简述
    Java 并发之原子性与可见性
    JVM 简述
    【算法导论】第5章,概率分析和随机算法
    【算法导论】第3、4章,增长和递归式
    【python】matplotlib进阶
    【dlbook】实践方法论
    【dlbook】优化
    【dlbook】正则化
    【dlbook】深度网络
  • 原文地址:https://www.cnblogs.com/qcblog/p/6858947.html
Copyright © 2011-2022 走看看