一、函数柯里化
定义:把接收多个参数的函数,转成接收单一参数的函数,并且返回余下参数的函数的过程就叫做函数柯里化
简单示例如下:
// 正常函数
function add(a, b){
return a + b
}
add(1, 2)
// 转成柯里化函数
function add(a){
return function(b){
return a + b
}
}
add(1)(2)
// 数字校验应用
const reg = /^\d+$/
// check函数就相当于是一个公用的函数,这是柯里化的一个好处,提取公共参数
const check = function(regexp){
return function(v){
return regexp.test(v)
}
}
const isNumber = check(reg)
源码实现函数柯里化
// 支持多参数传递
function currying(fn, ...args) {
var self = this
var len = fn.length;
var args = args || [];
return function() {
var _args = Array.prototype.slice.call(arguments);
Array.prototype.push.apply(args, _args);
// 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
if (_args.length < len) {
return currying.call(self, fn, _args);
}
// 参数收集完毕,则执行fn
return fn.apply(this, _args);
}
}
二、Compose与Pipe函数
描述:对于现在前端来说,大多数都是基于函数式编程的,因此在需要执行批量函数的时候,就需要使用Compose函数或Pipe函数
源码如下:
function compose() {
const fns = Array.from(arguments)
var bool = fns.every(fn => toString.call(fn) === '[object Function]')
if (!bool) {
throw new Error('every params must be a function')
}
return function (e) {
return fns.reduceRight((pre, cur) => cur(pre), e)
}
}
function pipe() {
const fns = Array.from(arguments)
var bool = fns.every(fn => toString.call(fn) === '[object Function]')
if (!bool) {
throw new Error('every params must be a function')
}
return function (e) {
return fns.reduce((pre, cur) => cur(pre), e)
}
}
三、函数防抖
描述:函数防抖(debounce):当持续触发函数时,函数不执行,间隔一段时间后再执行。 防抖即防止抖动,这里的函数防抖时防止函数多次执行,抖动时高频率且无规律的,如果高频率的触发函数势必会对性能造成影响,因此,为防止高频触发函数,我们要做函数防抖处理,举个例子:input的输入,每次input输入后都需要去数据库比对当前输入的值是否存在,用户一直在输入,如果每次输入就要去数据库比对那触发就太频繁了,为此我们可以加防抖,当用户不再输入后间隔一段时间再去执行相应的函数。
function debounce(fn, delay) {
//防抖
var delay = delay || 500;
var timer;
return function () {
var th = this;
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
timer = null;
fn.apply(th, args);
}, delay);
};
}
四、函数节流
描述:函数节流(throttle):当持续触发函数时,保证一段时间内只执行一次函数。节流即节省流量,比如水龙头放水,把水龙头关小,水流量就会降低,这样就能保证即放水又不会浪费。举个例子:scroll事件,用户下拉加载数据,一直刷新,一秒钟操作了十回,但一秒钟内只执行一回,这样保证一秒钟时间内,至少执行了一回,又不频繁触发函数。
function throttle(fn, interval) {
var last;
var timer;
var interval = interval || 500;
return function () {
var th = this;
var args = arguments;
var now = +new Date();
if (last && now - last < interval) {
clearTimeout(timer);
timer = setTimeout(function () {
last = now;
fn.apply(th, args);
}, interval);
} else {
last = now;
fn.apply(th, args);
}
}
}