闭包
- 函数外内访问到函数内部作用域的变量
- 且内部变量不会被清除 (过多会有可能导致内存泄漏)
- 形成:返回函数有使用到内部函数作用域的变量
防抖 debounce(只要一直触发就不会执行)
- 一直触发的事件,当触发停止时,才会执行函数。
- 常用场景:Input输入框,只会在停止输入后,delay时间后执行函数才获取值
// 防抖执行函数
const debounceFn = (e) => {
console.log("防抖函数execute", e);
};
// 防抖 一直点击,则只会触发最后一次
const debounce = (fn, delay) => {
let timer = null; //闭包 定时器变量
return function (e) {
if (timer) {
//定时器变量存在说明,已经点击过
//则需要 清除变量
clearTimeout(timer);
}
// 使得函数触发时间 是最后一次点击的delay时间
timer = setTimeout(() => fn(e), delay);
};
};
// 执行debounce返回类型是可执行函数
const execDebounce = debounce(debounceFn, 5000); //type ()=>function;
// 验证 (只要一直点击就不会执行 debounceFn )
document.querySelector("#btn").addEventListener("click", (e) => {
execDebounce(e); //执行返回的函数
});
节流 throttle(时间间隔内,只会执行一次)
- 相对防抖较不常用
- 需求:5秒内只发一次请求。
- 不管触发点击多少次,只会执行最开始的一次
// 节流实际执行函数
const throttleFn = (e) => {
console.log("节流函数execute", e);
};
// 节流 时间间隔内只执行一次
const throttle = (fn, delay) => {
let startTime = Date.now();
let timer = null; //闭包 定时器变量
return (params) => {
const curTime = Date.now();
const restTime = delay - (curTime - startTime);
clearTimeout(timer);
if (restTime <= 0) {
//说明时间已超过
fn.apply(this,[...params]);
} else {
timer = setTimeout(() => {
fn.apply(this,[...params]);
startTime = Date.now();
},restTime);
}
};
};
const execThrottle = throttle(throttleFn, 3000); //type ()=>function;
document.querySelector("#btn").addEventListener("click", (e) => {
execThrottle(e); //执行返回的函数
});
推荐在线编辑器:
- 传送门:codesandbox (与vsCode极其相似)
- 传送门:codepan (简约)