双语面试:实现一个防抖函数

124 阅读1分钟

面试题 Interview Question

实现一个支持 leading 选项的防抖函数 debounce
Implement a debounce function using pure functional programming (FP), and support the leading option.

要求 Requirements

  1. debounce(fn, wait, options) 接收三个参数:
    debounce(fn, wait, options) accepts three parameters:

    • fn:要防抖执行的函数
      fn: the function to debounce
    • wait:等待时间(毫秒)
      wait: wait time in milliseconds
    • options:配置项对象,可能包含 leading: true 表示是否立即执行
      options: an optional object; if it has leading: true, the function should fire immediately on the leading edge
  2. 返回的新函数应满足:
    The returned function should:

    • 在连续快速调用时,仅在最后一次调用后的 wait 毫秒后才执行(除非开启了 leading)
      Call fn only once, after wait milliseconds of no calls, unless leading is true
    • 如果 leading: true,第一次调用会立即执行,后续调用会忽略直到 wait 毫秒后
      If leading: true, invoke fn immediately on the first call, then ignore until wait expires
  3. 要求纯函数式风格,不使用 this 和类相关语法
    Pure functional style: do not use this or class-based syntax

参考答案 Reference Solution

function debounce(fn, wait, options = {}) {
  let timerId = null;
  let lastInvokeTime = 0;
  const { leading = false } = options;

  return function (...args) {
    const now = Date.now();
    const callNow = leading && !timerId;

    const invoke = () => {
      timerId = null;
      if (!leading) {
        fn(...args);
      }
    };

    if (callNow) {
      lastInvokeTime = now;
      fn(...args);
    }

    clearTimeout(timerId);
    timerId = setTimeout(invoke, wait);
  };
}

示例 Example

const log = (...args) => console.log('触发 Triggered:', ...args);

const debounced = debounce(log, 1000, { leading: true });

// 连续快速调用 3 次,只会立即触发一次,之后忽略直到 1000ms 后
debounced('click 1');
debounced('click 2');
debounced('click 3');

面试考察点 Interview Focus

  • 对节流和防抖机制的理解
    Understanding of throttling vs. debouncing

  • 对函数式编程原则的掌握(无副作用、无 this)
    Mastery of functional programming principles (no this, side-effect management)

  • 熟练掌握闭包、计时器以及时间控制
    Proficiency with closures, timers, and time-based logic