防抖
频繁触发的函数,只会执行最后一次
应用场景:表单验证、模糊查询等
function debounce(fn, timeout = 300) {
let timer;
return function () {
let context = this;
let args = arguments;
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn && fn.apply(context, args);
}, timeout);
}
}
节流
频繁触发的函数,在一段时间内只执行一次
应用场景:如鼠标移动事件等
function throttle(fn, timeout = 300) {
let timer;
return function () {
let context = this;
let args = arguments;
if(!timer) {
timer = setTimeout(function () {
fn && fn.apply(context, args);
clearTimeout(timer);
timer = null;
}, timeout);
}
}
}
柯里化
将接收多个参数的函数变为只接受一个单一的参数的函数,并返回接收余下参数的函数和返回结果的新函数
应用场景:延迟计算,参数复用,动态生成函数
// 例子
// 原函数,用来返回参数a + 参数b 的结果
function increment(a, b) {
return a + b;
}
// 将increment函数柯里化之后
function curryingIncrement(a) {
// 只接受一个参数,返回一个接收余下参数的函数
return function (b) {
// 被返回的函数返回了计算结果的新函数
return function() {
return a + b;
};
}
}
increment(10, 20); // 30
// 柯里化后执行如下
curryingIncrement(10)(20); // 30
封装代码
function currying(fn) {
let args = [];
// 返回一个命名的函数便于递归使用,也可以使用arguments.callee,但是这在严格模式下禁用
return function next() {
let arg = arguments;
args = [...args, ...arg];
// 若参数个数大于0 返回next
if(arg.length > 0) {
return next;
} else {
// 参数格式等于0,返回计算结果的函数
let context = this;
return fn.apply(context, args);
}
};
}
// ===== 测试函数功能 ===== //
// 原函数, 功能:返回参数相加的结果
function increment() {
let args = arguments;
let result = 0;
for (let i = 0; i < args.length; i++) {
result += args[i];
}
return result;
}
// 柯里化之后
let add = currying(increment);
add(10, 10, 10)(20)(30)(); // 80