为什么这个节流函数中的事件监听器会这样?
why does the event listener in this throttling function behave like that?
当我学习 throttling in javascript 时,我遇到了一个我无法解释的事件侦听器行为。这是一个简单的节流功能。
const btn=document.querySelector("#throttle");
// Throttling Function
const throttleFunction=(func, delay)=>{
// Previously called time of the function
let prev = 0;
console.log(prev); //This gets called only once and it is even before the button is clicked
return (...args) => {
// Current called time of the function
let now = new Date().getTime();
// Logging the difference between previously
// called and current called timings
console.log(now-prev, delay); //This however doesn't get called before the button is clicked
// If difference is greater than delay call
// the function again.
if(now - prev> delay){
prev = now;
// "..." is the spread operator here
// returning the function with the
// array of arguments
return func(...args);
}
}
}
btn.addEventListener("click", throttleFunction(()=>{
console.log("button is clicked")
}, 1500));
<button id="throttle">Click Me</button>
我有两个问题。
- 为什么
let prev = 0;
只被调用一次?即为什么不
prev
每次调用函数时都重置为 0?
- 我还注意到
let prev = 0;
在按钮被点击之前就被调用了,为什么会这样?为什么在单击按钮之前没有调用其余函数?
This 是我找到上面代码的地方。我在 MDN 上查看了 addEventListener
但无济于事。任何帮助将不胜感激。
.addEventListener()
方法将对函数的引用作为它的第二个参数,它可以在单击按钮时调用它。所以像这样的东西将无法添加函数作为点击事件处理程序:
const sayHello = () => console.log("hello");
btn.addEventListener("click", sayHello());
在上面的例子中JavaScript:
看到对 addEventListener()
的调用
计算其参数,这意味着调用 sayHello()
函数。
2.1。 sayHello()
运行并 returns undefined
使用 "click"
和 undefined
(评估的参数)调用 addEventListener()
方法
sayHello()
上方是一个函数调用,因此它将在添加事件侦听器时以及在发生任何点击之前执行,从而导致使用 sayHello
的 return 值作为 addEventListener()
的第二个参数,所以上面的代码将计算如下:
const sayHello = () => console.log("hello");
btn.addEventListener("click", undefined);
要正确传递对事件侦听器的引用,您需要传递一个函数,该函数稍后可以在发生点击时由 JS 调用:
btn.addEventListener("click", sayHello);
考虑到这一点,当您添加事件侦听器时会调用您的 throttleFunction()
参数,这意味着 throttleFunction
本身并不是作为第二个参数传递给 addEventListener()
,而是 return 值。如果将回调提取到 throttleFunction
:
,这可能会更清楚一些
const fn = () => {console.log("button is clicked")};
// invoking the `throttleFunction` function with `()`
const clickHandler = throttleFunction(fn, 1500);
btn.addEventListener("click", clickHandler); // clickHandler is a reference to a function (a non-invoked/called function)
由于正在调用您的 throttleFunction()
函数,throttleFunction
中的 returned 函数被用作 addEventListener()
的参数,而不是 throttleFunction 本身。 returned 函数只有在点击发生时才会执行。结果,let prev = 0;
在第一次调用throttleFunction时执行一次,也就是添加点击事件监听时,但是returned函数执行了多次,因为JS只有在点击时才会调用它在你的按钮上。
当我学习 throttling in javascript 时,我遇到了一个我无法解释的事件侦听器行为。这是一个简单的节流功能。
const btn=document.querySelector("#throttle");
// Throttling Function
const throttleFunction=(func, delay)=>{
// Previously called time of the function
let prev = 0;
console.log(prev); //This gets called only once and it is even before the button is clicked
return (...args) => {
// Current called time of the function
let now = new Date().getTime();
// Logging the difference between previously
// called and current called timings
console.log(now-prev, delay); //This however doesn't get called before the button is clicked
// If difference is greater than delay call
// the function again.
if(now - prev> delay){
prev = now;
// "..." is the spread operator here
// returning the function with the
// array of arguments
return func(...args);
}
}
}
btn.addEventListener("click", throttleFunction(()=>{
console.log("button is clicked")
}, 1500));
<button id="throttle">Click Me</button>
我有两个问题。
- 为什么
let prev = 0;
只被调用一次?即为什么不prev
每次调用函数时都重置为 0? - 我还注意到
let prev = 0;
在按钮被点击之前就被调用了,为什么会这样?为什么在单击按钮之前没有调用其余函数?
This 是我找到上面代码的地方。我在 MDN 上查看了 addEventListener
但无济于事。任何帮助将不胜感激。
.addEventListener()
方法将对函数的引用作为它的第二个参数,它可以在单击按钮时调用它。所以像这样的东西将无法添加函数作为点击事件处理程序:
const sayHello = () => console.log("hello");
btn.addEventListener("click", sayHello());
在上面的例子中JavaScript:
看到对
的调用addEventListener()
计算其参数,这意味着调用
sayHello()
函数。2.1。
sayHello()
运行并 returnsundefined
使用
"click"
和undefined
(评估的参数)调用addEventListener()
方法
sayHello()
上方是一个函数调用,因此它将在添加事件侦听器时以及在发生任何点击之前执行,从而导致使用 sayHello
的 return 值作为 addEventListener()
的第二个参数,所以上面的代码将计算如下:
const sayHello = () => console.log("hello");
btn.addEventListener("click", undefined);
要正确传递对事件侦听器的引用,您需要传递一个函数,该函数稍后可以在发生点击时由 JS 调用:
btn.addEventListener("click", sayHello);
考虑到这一点,当您添加事件侦听器时会调用您的 throttleFunction()
参数,这意味着 throttleFunction
本身并不是作为第二个参数传递给 addEventListener()
,而是 return 值。如果将回调提取到 throttleFunction
:
const fn = () => {console.log("button is clicked")};
// invoking the `throttleFunction` function with `()`
const clickHandler = throttleFunction(fn, 1500);
btn.addEventListener("click", clickHandler); // clickHandler is a reference to a function (a non-invoked/called function)
由于正在调用您的 throttleFunction()
函数,throttleFunction
中的 returned 函数被用作 addEventListener()
的参数,而不是 throttleFunction 本身。 returned 函数只有在点击发生时才会执行。结果,let prev = 0;
在第一次调用throttleFunction时执行一次,也就是添加点击事件监听时,但是returned函数执行了多次,因为JS只有在点击时才会调用它在你的按钮上。