前端经典面试题解密-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)())
*后:有不清楚的地方,伙伴们可以留言,今天的教程先到这里,另外给伙伴们些干货,可以私下给自己镀镀金!
Web前端全套视频教程https://pan.baidu.com/s/1a2xUpK5CwoV3qB7GB04RfQ 提取码:uuai