返回
防抖和节流之闭包中this,你抓住了吗?
前端
2023-10-25 08:42:24
闭包与this
闭包是 JavaScript 中的一个重要概念,是指函数访问其定义所在域之外的变量。JavaScript 中的 this 是指向当前执行函数的对象,对于普通函数,this 指向谁由该函数的调用方式决定,而箭头函数则不受调用方式影响,始终指向创建它的对象。
防抖和节流
防抖和节流是两种常见的技术,用于在事件频繁触发时,优化函数的执行频率。
- 防抖:在规定时间内,函数只能执行一次。
- 节流:在规定时间内,函数只能执行固定次数。
闭包在防抖和节流中的应用
在防抖和节流中,通常需要使用闭包来保存定时器。定时器是一个函数,将在指定的时间后执行。闭包可以确保定时器在函数执行后不会被清除。
普通函数中的this指向问题
在防抖和节流闭包中,使用普通函数时,this 的指向会受到调用方式的影响。
- 当使用事件监听器调用函数时,this 指向触发事件的元素。
- 当使用 setTimeout 或 setInterval 调用函数时,this 指向 window 对象。
箭头函数中的this指向
使用箭头函数定义闭包时,this 的指向不受调用方式的影响,始终指向创建它的对象。
使用普通函数和箭头函数的比较
使用普通函数和箭头函数定义防抖和节流闭包的优缺点如下:
普通函数:
优点:在某些情况下可以方便地访问 this,例如事件监听器。
缺点:this 的指向受调用方式的影响。
箭头函数:
优点:this 的指向始终指向创建它的对象,不需要担心 this 的指向问题。
缺点:无法使用 普通函数 的 this 。
使用闭包的防抖和节流示例
以下是一个使用闭包的防抖示例:
function debounce(fn, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
以下是一个使用闭包的节流示例:
function throttle(fn, delay) {
let timer = null;
let lastCall = 0;
return function () {
const now = Date.now();
if (now - lastCall < delay) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
lastCall = now;
}, delay);
} else {
fn.apply(this, arguments);
lastCall = now;
}
};
}
结论
闭包对于防抖和节流至关重要,它可以确保定时器在函数执行后不会被清除。在使用闭包定义防抖和节流函数时,要注意 this 的指向问题。在普通函数中,this 的指向受调用方式的影响,而在箭头函数中,this 的指向始终指向创建它的对象。