A common debounce implementation captures `this` and `args` and calls `fn.apply(this, args)` inside the timeout. Why is `apply(this, args)` used instead of just `fn()`?
function debounce(fn, wait) {
let t;
return function (...args) {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), wait);
};
}