Debouncing delays execution until a quiet period elapses. Throttling guarantees execution at most once per interval. Memoization caches pure function outputs by argument.
js
function debounce(fn, ms) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), ms);
};
}