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实现
    Hanoi问题java解法
    j2ee之Filter使用实例(页面跳转)
    java工具类之Graphics
    java程序设计之循环链表
    Java程序设计求出岁数
    Java程序设计之链表结构
    CENTOS 6 通过YUM升级GCC到4.7/4.8
    Object c的NSString的使用,创建,拼接和分隔,子string,substring
    Let’s Encrypt 最近很火的免费SSL 使用教程
  • 原文地址:https://www.cnblogs.com/qcblog/p/6858947.html
Copyright © 2011-2022 走看看