理解一下防抖和节流

引言

防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。

一. 防抖

1.1 防抖是啥

  • 比如你写的input的onchange事件,每次改变input里的内容,浏览器都会去服务器索要东西。其实浏览器想要的只是最终你输入的结果,浏览器只想发送一次。防抖的目的就是咋做,使得就发送那最后一次。

1.2 手写防抖

1.2.1基础版

只要0.5秒之内没输入,就向后端发送数据(业务逻辑),执行完一次业务逻辑之后,时间计时器清空,重新开始。

<!DOCTYPE html>
<html lang="en">
  <body>
    <input id="111" type="text" placeholder="555" />
    <script>
      let t = null;
      let inp = document.getElementById("111");
      inp.onchange = function () {
        // onchange事件是HTML里input标签支持的表单事件:
        // 参考:https://www.w3cschool.cn/htmltags/ref-eventattributes.html
        if (t !== null) {
          clearTimeout(t);
        }
        t = setTimeout(() => {
          console.log(this.value); //业务逻辑
        }, 500); // 0.5秒之内没输入,就执行业务逻辑
      };
    </script>
  </body>
</html>
1.2.2升级版

这里针对防抖进行了一个闭包函数封装

<!DOCTYPE html>
<html lang="en">
  <body>
    <input id="111" type="text" placeholder="555" />
    <script>
      let inp = document.getElementById("111");
      inp.onchange = debounce(function () {
        console.log(this.value); // 
      }, 500);

      //封装一个防抖的闭包函数
      function debounce(fn, delay) {
        let t = null;// 这个变量会一直在内存中(比如你关闭一个程序,任务管理器中看见该程序内存还有占用就是这种东西)
        return function () {
          if (t !== null) {
            clearTimeout(t);
          }
          t = setTimeout(() => {
          	//fn(); // 此时的this指向window ①
            fn.call(this); //改变this指向:指向input + 执行业务逻辑 ②
          }, delay); // delay毫秒之内没输入,就执行业务逻辑
        };
      }
    </script>
  </body>
</html>

①:这里的this指向window—(后边有解析)
②:这里的this指向inp—(后边有解析)
通过A.call(B)使B来调用A,并且立即执行 :A是想被调用的函数,B一般指this,通过call()使inp调用fn()

二. 节流

1.1 节流是啥

  • eg:鼠标滚动的时候会触发ajax事件,因为滚动时候的触发的频率太高了,所以我要降低这个触发的频率。这个就是节流

1.2 手写节流

// 节流,这个书写方式和防抖的一样
window.onscroll = throttle(function () {
    console.log("节流");
}, 500);

function throttle(fn, delay) {
    let flag = true;
    return function () {
        if (flag) {
            setTimeout(() => {
                fn.call(this);
                flag = true;
            }, delay)
        }
        flag = false;
    }
}

三. 知识点

3.1. 改变this指针的三种方式

1、fn.call(obj, 1, 2); // 使obj来调用fn,fn立即执行,传递参数的情形比较少见
2、fn.bind(obj, 1, 2); // 使obj来调用fn,fn不立即执行,传递参数的情形比较少见
3、fn.apply(obj, [1, 2]);//使obj来调用fn,fn立即执行,参数传递是数组的形式,但是实质上还是一个一个传。

3.2. 为什么①的this指向window,②的this指向input

  • this指向的规则:谁调用的指向谁。
  • 在①里,源头是fn调用产生的,但是fn自己没有this,于是就向上找,就找到了定义debounce时候的window。
  • 在②里,通过A.call(B)使B来调用A:此时的B就是inp.onchange,所以此时的this指向inp。

3.3. 附一个我总结的this指向问题解析

  1. 直接写:指向window
  2. 方法:对象.方法() 指向对象
  3. new:var a = new b(this) this指向a
  4. 箭头函数:指向外一层的 this

3.4. new的时候发生了什么

1、创建一个新对象Obj
2、将新对象(Obj)的_proto_指向构造函数(Person)的prototype对象
3、将构造函数的作用域赋值给新对象 (this指向新创建的对象Obj)
4、执行构造函数中的代码(为这个新对象添加属性)
5、返回新的对象

var Obj = {};
Obj.proto = Person.prototype();
Person.call(Obj);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值