JavaScript中防抖函数返回函数的触发机制解析
防抖函数内部返回函数的触发原理
问题描述
我编写了如下防抖函数代码:
const selectElement = document.querySelector('input'); const debounce = (cb, time = 1000) => { let timer; return (...args) => { console.log('run inner function') if (timer) { clearTimeout(timer) } timer = setTimeout(() => cb(...args), time) } } const onChange = debounce((e) => { console.log('event', e.target.value) }) selectElement.addEventListener('input', onChange);
<input input={onChange}/>
上述代码运行正常,但我想理解防抖函数内部返回的函数是如何被触发的。我了解通常返回函数的函数需要通过debounce()()的方式调用才能触发内部函数,但此处仅调用一次debounce()得到onChange并传入addEventListener,内部函数却能执行,希望知晓其中原理。
原理解析
debounce是高阶函数,返回的是一个函数
调用debounce((e) => {...})时,并不会执行内部那个带console.log('run inner function')的箭头函数,而是直接把这个箭头函数作为返回值赋值给了onChange变量。此时onChange就是那个内部返回的函数本身。addEventListener会自动调用传入的函数
addEventListener('input', onChange)的作用是:告诉浏览器——当input元素触发input事件时,去调用onChange这个函数。所以当你在输入框输入内容时,浏览器会自动执行onChange(e)(这里的e是事件对象),这就触发了防抖函数返回的内部函数。和手动调用的区别
你之前理解的debounce()()是手动触发内部函数:第一次调用debounce()拿到返回的函数,第二次括号是手动执行它。而这里是把返回的函数交给了浏览器的事件系统,由事件系统在合适的时机自动执行它,本质上和你手动写onChange()是一样的,只是调用的主体从你变成了浏览器。
举个极简例子辅助理解:
// 一个返回函数的函数 const outer = () => { return () => console.log('内部函数执行了') } // 拿到内部函数 const inner = outer() // 手动调用内部函数 inner() // 打印"内部函数执行了" // 或者把inner传给事件监听,由浏览器调用 document.querySelector('button').addEventListener('click', inner) // 点击按钮时,浏览器会自动调用inner(),同样打印内容
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

