Salesforce 前端面试真题:Implement Debounce in JavaScript

这是一道 Salesforce 前端面试中出现的 JavaScript 基础实现题。面试记录显示,这一轮明确属于 Frontend 面试,并允许候选人使用 JavaScript 或 TypeScript 作答。

Implement debounce in JS.

实现一个 debounce 函数。

当一个函数在短时间内被连续调用时,不要每次都立即执行,而是在停止调用一段时间后,只执行最后一次。


const handleSearch = debounce((keyword) => {
  console.log("Searching:", keyword);
}, 300);

handleSearch("s");
handleSearch("sa");
handleSearch("sal");
handleSearch("salesforce");

上面的调用发生在很短的时间内,最终只会执行一次:

Searching: salesforce

function debounce(fn, delay) {
  let timer = null;

  return function (...args) {
    clearTimeout(timer);

    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

使用方式

const debouncedSearch = debounce(function (keyword) {
  console.log("Search:", keyword);
}, 500);

debouncedSearch("Sales");
debouncedSearch("Salesforce");

每次调用返回函数时,都会先清除之前的定时器,再创建新的定时器。

只有在连续 500ms 没有新的调用后,原函数才会真正执行。


为什么要使用 apply

下面这种写法虽然简单:

setTimeout(() => {
  fn(...args);
}, delay);

但更完整的实现通常会写成:

fn.apply(this, args);

这样可以保留函数调用时的 this

例如:

const user = {
  name: "Salesforce",

  printName: debounce(function () {
    console.log(this.name);
  }, 300),
};

user.printName();

输出:

Salesforce

如果错误地丢失了 this,输出可能会变成 undefined

面试官继续追问

  1. 如何保留参数和 this
  2. 如何增加 cancel 方法?
  3. 如何实现第一次立即执行?
  4. 如何同时支持 leading 和 trailing?
  5. debounce 和 throttle 有什么区别?
  6. React 中使用 debounce 时需要注意什么?
  7. 组件卸载时如何取消未执行的定时器?

在 React 中,常见问题是每次渲染都重新创建 debounced 函数:

function Search() {
  const handleSearch = debounce((value) => {
    console.log(value);
  }, 300);
}

更合理的方式是使用 useMemouseCallback 保持函数引用稳定,并在组件卸载时调用 cancel


这道题代码量不大,主要考察:

  • 对闭包的理解
  • setTimeoutclearTimeout
  • 参数透传
  • this 绑定
  • 边界情况处理
  • 是否能够根据追问扩展功能

面试时可以先完成基础 trailing debounce,再主动说明可以继续支持 cancel、立即执行以及 TypeScript 类型。相比一开始就写非常复杂的版本,这样更容易保证正确性。


CSOAHelp 提供北美大厂面试实时文本辅助与 Mock Interview 服务,覆盖前端、全栈、算法和系统设计面试。

我们也有代面试,面试辅助,OA代写等服务助您早日上岸~

Leave a Reply

Your email address will not be published. Required fields are marked *