JavaScript 防抖函数,绑定事件后事件对象传参问题

2022-09-12 14:48:29 +08:00
 WNW

明明事件对象 e 是作为的 debounce 中的第一个 fn 函数参数,为什么能够被 debounce 函数返回的匿名函数中 的...args 获取得到呢?实在想不通,不知道有哪位同学可以答疑解惑,不胜感激

// 防抖
function debounce(func, wait = 500) {

  let timeID;

  return function (...args) {

    if (timeID) clearTimeout(timeID);
    timeID = setTimeout(() => {
      func.apply(this, args);
    }, wait);
    
  }

}

let password = document.querySelector('[name="password"]');


// 明明事件对象 e 是作为的 debounce 中的第一个 fn 函数参数,为什么能够被 debounce 函数返回的匿名函数中
// 的...args 获取得到呢?实在想不通,不知道有哪位同学可以答疑解惑,不胜感激

password.addEventListener("keyup", debounce(function (e) { 
	console.log(222) 
}, 500));




2301 次点击
所在节点    程序员
17 条回复
zjffun
2022-09-12 15:20:45 +08:00
debounce 返回的是一个函数,可以先分析这个更简单的流程看看

```js
function debounce(func) {
return function (...args) {
console.log("args", args);
func(...args);
};
}

let password = document.querySelector('[name="password"]');

const debouncedFn = debounce(function (e) {
console.log(222);
});

console.log("debouncedFn", debouncedFn);

password.addEventListener("keyup", debouncedFn);
```
zjffun
2022-09-12 15:28:51 +08:00
WNW
2022-09-12 15:52:09 +08:00
@zjffun 好的谢谢,我先试试
Justin13
2022-09-12 17:47:16 +08:00
因为你绑定的就是 debounce 的返回值
dasbn
2022-09-12 17:56:58 +08:00
因为你使用的就是 debounce 函数返回的匿名函数 , 原函数已经被包起来了,func.apply(this, args); 这一句就是调用原来的函数。并不是匿名函数获取对象 e ,而是匿名函数把 e 传递给原来的函数作为参数。
walking50w
2022-09-12 18:02:11 +08:00
```
function debounce(func, wait = 500) {

let timeID;

return function fn(...args) {

if (timeID) clearTimeout(timeID);
timeID = setTimeout(() => {
func.apply(this, args);
}, wait);

}

}

```
walking50w
2022-09-12 18:08:59 +08:00
@silasamiseaf94
// 重新命名, 简化
debounce(outer, wait = 500) {
function inner(e) {
outer.apply(null, e)
}
return inner
}
// callback 执行顺序
// 延时后
onKeyup => inner(e) => outer(e)
// 所以 outer 中 e 来自 inner
WNW
2022-09-12 20:10:47 +08:00
@dasbn 问题是匿名函数得先获取才能传递啊,我疑惑的就是匿名函数是怎么获取得到 e 的,获取到了才能再传递
WNW
2022-09-12 20:14:36 +08:00
@silasamiseaf94 了解明白了
WNW
2022-09-12 20:36:46 +08:00
@silasamiseaf94 我知道 outer 的 e 来自 inner,问题只 inner 的 e 是从哪儿来的?
walking50w
2022-09-12 21:12:38 +08:00
@WNW 我的天,debounce 返回的 inner 作为 onKeyup 的回调, 回调触发事件,调用 inner 注入 e 参数
demonzoo
2022-09-12 21:38:57 +08:00
说实话没太看懂你的问题点在哪里,单说 args 的话不就是个闭包?
WNW
2022-09-13 09:30:36 +08:00
@silasamiseaf94 可是 e 明明传给的是 debounce 的第一个 outer 作为 outer 的参数 outer(e),在还没有返回闭包也就是 inner 的时候 e 是随着 outer 先进入 debounce 函数第一层,我的疑惑就是 outer(e)带着 e 进来,这个 e 是怎么被 inner(...args)获取得到的,我知道 inner 里面又从新把 e 通过 apply 再次传递给 outer 了
WNW
2022-09-13 09:41:46 +08:00
@silasamiseaf94
password.addEventListener("keyup", debounce(function (e) {
console.log(222)
}));
这里调用的 debounce 的 function(e){} 就是你的 outer,如果按你的理解其实 e 传给的实际上是 inner(...agrs),这个 e 第一步 debounce 执行的时候是直接传给了返回的闭包也就是 inner(...agrs)被...agrs 获取了再传给 outer 了
walking50w
2022-09-13 11:39:36 +08:00
@WNW addEventListener 的时候,先执行了 debounce() ,实际绑定的是 debounce 执行后返回的函数 inner 。

addEventListener('keyup', debounce(fn, 500) )
== let inner = debounce(fn, 500); addEventListener('keyup', inner )
// 整个流程的顺序是 先执行 debounce()函数,debounce 返回了新的函数 inner , 新的函数作为 keyup 事件的回调函数。
事件出发后 inner 执行,inner 中再去调用 outer
DICK23
2022-09-13 11:50:05 +08:00
就是一个占位参数,绑定返回后的函数的参数
WNW
2022-09-13 14:30:37 +08:00
@silasamiseaf94 明白了,感谢感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/879440

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX