手撕JS面试题代码(一) — 防抖与节流的实现

677 阅读1分钟

防抖

防抖是在触发事件的n秒之后才会执行函数,触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

应用场景

  • 按钮点击事件
  • input事件
  • 手机号验证
  • 防止用户多次重复提交
  • ...
//每次触发事件时都取消之前的延时调用方法
const debounce = (func, time) => {
    if (typeof func !== 'function') {
        throw new TypeError('Expected a function')
    }
    const wait = +time || 500
    let timeout = null
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            console.log(arguments);
            func.apply(this, arguments);
        }, wait);
    };
}

节流

高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

应用场景

  • 判断页面滚动加载
  • 高频发送请求
  • ...
//每次触发事件时都判断当前是否有等待执行的延时函数
const throttle = (func, time) => {
    if (typeof func !== 'function') {
        throw new TypeError('Expected a function')
    }
    const wait = +time || 500
    let canRun = true;
    return function () {
        if (!canRun) return;
        canRun = false;
        func.apply(this, arguments);
        setTimeout(() => {
            canRun = true;
        }, wait);
    };
}

注意点:使用call或者apply改变保证this指向

下图(非原创)能很清楚的演示在 mousemove 情况下

防抖(debounce)和节流(throttle)表现上的差异。