zoukankan      html  css  js  c++  java
  • 前端经典面试题解密-add(1)(2)(3)(4) == 10到底是个啥?

    前言

    前端的小伙伴在面试的时候,几乎都会遇到一道这样的面试题: add(1)(2)(3)(4)输出结果为10。在第一次看到这道面试题的时候,很多小伙伴感到了迷茫!借用王宝强在《人在囧途》中的表演:啥啥啥,这写的都是啥?下面胡哥为各位小伙伴带来这道题的揭秘。

    一、核心点-基础函数的变种-函数柯里化

    我们从0开始,一点点儿的观察。add(1)(2)(3)(4)输出的值怎么成为10,很简单,大家都明白是1+2+3+4的累加。那使用基础函数是怎么实现的呢?

    function add (a, b, c, d) {
    	return a + b + c + d
    }
    add(1, 2, 3, 4) // 10
    

    那如何add(1)(2)(3)(4)如何也输出10呢?小伙伴接下来可能会想到这样:

    function add (a) {
    	return function (b) {
    		return function (c) {
    			return function (d) {
    				return a + b + c + d
    			}
    		}
    	}
    }
    

    是不是很完美!

    但是如果你这么回答面试官,面试官肯定会立刻怼死你,累加到100怎么办?(PS:没有说10000已经很客气了)

    王老师经典语录:下面的是重点,圈起来,一定要考!!

    函数柯里化概念: 柯里化(Currying)是把接受多个参数的函数转变为接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术。

    二、函数柯里化解决方案

    函数柯里化有两种不同的场景,一种为函数参数个数定长的函数,另外一种为函数参数个数不定长的函数。

    1. 函数参数个数定长的柯里化解决方案

      // 定长参数
      function add (a, b, c, d) {
      	return [
      	  ...arguments
      	].reduce((a, b) => a + b)
      }
      
      function currying (fn) {
      	let len = fn.length
      	let args = []
      	return function _c (...newArgs) {
      		// 合并参数
      		args = [
      			...args,
      			...newArgs
      		]
      		// 判断当前参数集合args的长度是否 < 目标函数fn的需求参数长度
      		if (args.length < len) {
      			// 继续返回函数
      			return _c
      		} else {
      			// 返回执行结果
      			return fn.apply(this, args.slice(0, len))
      		}
      	}
      }
      let addCurry = currying(add)
      let total = addCurry(1)(2)(3)(4) // 同时支持addCurry(1)(2, 3)(4)该方式调用
      console.log(total) // 10
      
    2. 函数参数个数不定长的柯里化解决方案

      问题升级:那这个问题再升级一下,函数的参数个数不确定时,如何实现呢?

      function add (...args) {
      	return args.reduce((a, b) => a + b)
      }
      
      function currying (fn) {
      	let args = []
      	return function _c (...newArgs) {
      		if (newArgs.length) {
      			args = [
      				...args,
      				...newArgs
      			]
      			return _c
      		} else {
      			return fn.apply(this, args)
      		}
      	}
      }
      
      let addCurry = currying(add)
      // 注意调用方式的变化
      console.log(addCurry(1)(2)(3)(4, 5)())
      

    后记

    以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得收藏转发、点击右下角按钮在看,推荐给更多小伙伴呦,欢迎多多留言交流...

    胡哥有话说,一个有技术,有情怀的胡哥!现任京东前端攻城狮一枚。
    胡哥有话说,专注于大前端技术领域,分享前端系统架构,框架实现原理,最新最高效的技术实践!

    长按扫码关注,更帅更漂亮呦!关注胡哥有话说公众号,可与胡哥继续深入交流呦!

    胡哥有话说

  • 相关阅读:
    CentOS下安装vsftpd
    Linux下快速删除大量文件
    /var/spool/postfix/maildrop/ 中有大量的文件
    Linux 查看目录大小及文件数量命令
    windows下体验Redis
    hMailServer SSL 配置
    vmware 安装 Mac OS X 10.9 Mavericks
    提问和看不懂
    C 语言学习 第三次作业总结
    C 语言学习 第二次作业总结
  • 原文地址:https://www.cnblogs.com/justbecoder/p/12624736.html
Copyright © 2011-2022 走看看