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

  • 相关阅读:
    LeetCode236. 二叉树的最近公共祖先
    LeetCode235. 二叉搜索树的最近公共祖先
    LeetCode第32场双周赛
    .NET+Vue 使用SignalR推送数据
    Asp.Net Core使用MongoDB
    CentOS8 部署SqlServer
    windows 任何软件出现异常有日志 w3wp.exe [10608]中发生了未处理的Microsoft .Net Framework异常
    C# Socket使用以及DotNetty和Supersocket 框架
    C# 数据结构与算法 操作系统原理 计算机网络原理 数据库开发学习
    DotNet .Net Framework与Net Core与Net Standard 以及.NET5
  • 原文地址:https://www.cnblogs.com/qcblog/p/6858947.html
Copyright © 2011-2022 走看看