防抖和事件回调函数的问题(求解答)

关于前端防抖的疑问和理解

防抖

防抖简单来说就是为了防止前端界面用户频繁点击 button 按钮之后频繁发送 ajax 请求或者造成的事件阻塞。

解决思路:利用定时器,当用户点击 button 之后在某个时间(如:500 毫秒)之内再次点击 button 时,就清除定时器,重新计时。

执行代码

function fn(a) {
  console.log("被点击了!!");
}

function debounce(fn, delay) {
  var timer = null; // 声明计时器
  console.log(this, arguments);
  return function () {
    var context = this;
    var args = arguments;
    console.log(this, arguments);
    clearTimeout(timer);
    timer = setTimeout(function () {
      fn.apply(context, args);
    }, delay);
  };
}

// 绑定事件时:如果只是函数名fun,则事件执行之后才执行,
//如果为fun()传参数,事件创建时会执行fun,但是事件执行时会调用fun的回调return
document.getElementById("button").addEventListener("click", debounce(fn, 500));

几个问题

  1. 关于防抖函数中的 apply()函数,这个不是很好解释,建议结合https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call上的 call()函数一起理解。

  2. 一个事件回调的问题(没有想明白,求解释)

    function fun(a) {
      console.log("fun1");
      return function () {
        console.log("fun2");
      };
    }
    
    //回调函数为fun的时候,点击之后会执行fun,并且输出fun1, 但是fun的return之后的函数不会执行
    document.getElementById("button").addEventListener("click", fun);
    
    //回调函数为fun()的时候,页面加载的时候会输出fun1,但是点击之后才会执行return之后的function(){}
    document.getElementById("button").addEventListener("click", fun(1));
    

    我的问题:为什么当事件回调函数为 fun 时,事件执行时,执行的是 fun 函数 return 上面的部分。而当事件回调函数为 fun()时,return 上面的代码会在页面加载的时候就执行,而 return 后面的 function 函数会在事件(click)执行的时候才执行。求解!

事件绑定是什么,是绑定一个函数,在某一事件触发的时候执行。addEventListener第一个参数是事件名,第二个参数是回调函数,是回调函数,是回调函数!

上面的addEventListener("click", fun)写法,就是将fn绑定为事件的回调函数,每一次事件触发的时候都会执行fn,需要管fn里面是否返回函数吗,不需要,你只需要记住每次事件触发运行fn就行。

下面的addEventListener("click", fun(1))写法是什么,是先运行fun(1),将fun(1)的返回结果绑定为事件的回调函数,fun(1)的返回结果我们按照你的称呼是fun1,也就是说将fun1绑定为事件的回调函数,每一次事件触发的时候都会执行fun1

你这里迷惑的关键是,两个addEventListener传入的第二个参数不一样。你可以拆开来看:
document.getElementById("button").addEventListener("click", fun);
这里是在按钮点击的时候执行 fun 函数。

document.getElementById("button").addEventListener("click", fun(1));
上面的代码等价于:
const fn2 = fun(2)
document.getElementById("button").addEventListener("click", fn2);
也就是按钮点击的时候执行 fn2 函数。
此时我们知道fn2的值是 fun(2) 的结果,也就是fun return的函数。