本篇文章主要是介绍一下标题里面的概念,在面试的时候经常文档,结合阅读到的资料,结合本人的个人见解出品了该文章,如有写的不好的地方或理解有误的,还望阁下多多指教。
1、高阶函数
什么是高阶函数?
-
接受一个或多个函数作为输入
-
输出一个函数
在React中的高阶组件本质上就是高阶函数。我们在开发umi搭建出来的项目的时候,那个withRouter本质上就是一个高阶函数。
2、柯里化
柯里化概念:将一个多元函数,转成一个依次调用的单元函数。
柯里化特点:
- 返回一个函数
- 当接受参数数量与原函数形参数量相同,执行原函数
- 当小于形参数值,返回一个函数,用接收剩余参数,直到参数数量保持一致,才开始执行原函数。
举个例子,比如说我们有一个sum函数,接收a,b,c,d这四个参数,经过curry这个函数以后,可以依次传参数:
function sum(a, b, c, d) {
console.log(a, b, c, d);
}
var _sum = curry(sum);
var A = _sum(1)
var B = A(2)
var C = B(3)
var D = C(4)
那么curry这个函数具体是怎样的呢?来看一下代码:
function curry(fn) {
return function curriedFn() {
var args = Array.prototype.slice.call(arguments)
if (args.length < fn.length) {
// 参数不同
return function() {
var args2 = Array.prototype.slice.call(arguments)
// 开始递归
return curriedFn.apply(null, args.concat(args2))
}
}
// 参数相同
return fn(...args)
}
}
接下来看一下在面试的时候见到的一个面试真题:
实现一个方法add(1)(2)(3)
这个题目还可以变形,实现一个方法add(1,2)(3)或者add(1)(2,3);
不管如何变形,使得最后加和的结果都是相同的。
这道面试题我在面试的时候真的见面试官问过,其实是考察柯里化和闭包的,我当时对于柯里化这个概念理解的不是很透彻,没写出让面试官满意的结果,结果面试挂了,挂了不怕,来复盘一下吧,下次面试在遇到同样的问题,一定要能写出来呀,来看一下答案吧:
function add() {
var args = Array.prototype.slice.call(arguments);
var currying = function() {
args.push(...arguments);
return currying;
};
currying.getSum = function () {
return args.reduce(function (a, b) {
return a + b;
});
}
return currying;
}
console.log('查看demo:', add(1,2)(3)(4,5).getSum());
3、纯函数
纯函数定义:纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。
比如数组的 slice
和 splice,
-
slice
符合纯函数的定义:因为对相同的输入它保证能返回相同的输出; -
splice
却不同:会产生可观察到的副作用,即这个数组永久地改变了;