推荐答案
// www.javascriptcn.com code example
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
func.apply(this, args);
lastCall = now;
}
};
}
// 示例
function handleScroll() {
console.log("Scroll event triggered!");
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);本题详细解读
节流(Throttle)的概念
节流是指在一定时间间隔内,函数只能执行一次。 想象一下水龙头,即使你一直拧开,水流也只会以一定的速率流出,而不是立即倾泻而出。这和节流的原理相似。在前端开发中,一些事件(如 scroll、resize、鼠标移动等)可能会频繁触发,如果每次触发都执行回调函数,可能会导致性能问题。使用节流可以限制这些高频事件的触发频率,从而提升页面性能。
实现思路
- 时间戳记录: 需要一个变量来记录上次函数执行的时间戳。
- 计算时间差: 每次触发事件时,计算当前时间戳与上次函数执行时间戳的时间差。
- 条件判断: 如果时间差大于等于设定的延迟时间,则执行函数,并更新上次函数执行的时间戳。否则,什么都不做,直接返回。
代码详解
throttle(func, delay):- 接收两个参数:
func是需要节流的函数,delay是延迟的时间(毫秒)。 - 内部使用
lastCall变量记录上次函数执行的时间戳,初始化为0。 - 返回一个匿名函数,这个匿名函数就是节流后的函数。
- 接收两个参数:
(...args): 使用剩余参数语法来接收调用节流函数时传递的参数。const now = Date.now();: 获取当前时间戳。if (now - lastCall >= delay): 判断当前时间戳与上次执行时间戳的时间差是否大于等于延迟时间。func.apply(this, args);: 如果时间差满足条件,则使用apply调用原始函数,并将上下文设置为当前函数的this,传递接收到的参数args。lastCall = now;: 更新上次函数执行的时间戳为当前时间戳。
- 示例:
handleScroll是一个简单的示例函数,表示在滚动时触发的操作。throttle(handleScroll, 200)创建了一个节流后的滚动事件处理函数,延迟时间为200毫秒。window.addEventListener('scroll', throttledScroll);将节流后的函数添加到滚动事件监听器上。
为什么使用 apply?
使用 apply 的目的是为了确保被节流的函数在调用时,其 this 指向的是调用节流函数的上下文,同时可以传递调用时传入的参数。
优点
- 性能优化: 限制高频事件触发频率,避免频繁执行回调函数,提高页面性能。
- 简单易用: 实现简单,易于理解和使用。
注意事项
- 使用
Date.now()获取时间戳,精确度足够日常使用。 - 可以根据需要调整延迟时间
delay。 - 此实现会在首次触发时立即执行,之后在设定的延迟时间内才再次执行。 另一种节流的实现方法,会在延迟结束后才执行,即首次触发不执行,这里没有使用,需要注意区别。