防抖和节流

1.防抖函数:

防抖函数就是在一定时间内没再触发事件时,执行程序;常用于搜索框搜索功能的优化;避免过于频繁的发送请求;
思路:
1.触发事件,清除延时函数,创建新的延时函数,并计时;
2.如果再次触发事件,执行函数,会clearTimeout移除延迟函数,创建新的延迟函数重新计时;
3.只有在一定时间间隔内没再触发事件,程序便执行;

function debounce(func, delay) {
      var timer = null

      return function() {
        clearTimeout(timer)
        timer = setTimeout(func, delay)
      }
    }

关于this和参数的问题:

this的问题比较容易总结,就是关于this隐式绑定丢失的问题,当实现隐式绑定的函数进行赋值操作时【参数传递属于一种隐式赋值】,就会发生this丢失,比较常见的就是延时函数中的this,它的this指向window;

解决问题的方法:
1.借助ES6的箭头函数,箭头函数会继承外层函数调用的this绑定;
2.使用 var self = this,保留this的绑定;

下面讨论参数的问题

ES5语法:
function foo(a, b) {
      console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      setTimeout(function() {
        console.log(arguments);//Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
        console.log(event);//undefined
      }, 500)
    }

    // foo(10, 29)
    window.onload = function() {
      foo(22, 33)
    }

事件对象和arguments无法传递给延时函数

处理方法:
function foo(a, b) {
      console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      var _arguments = arguments
      console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      var _event = event
      setTimeout(function() {
        console.log(_arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
        console.log(_event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      }, 500)
    }

    // foo(10, 29)
    window.onload = function() {
      foo(22, 33)
    }

最终的基于ES5语法的防抖函数:

// 防抖函数
    function debounce(func, delay) {
      var timer = null

      return function() {
        clearTimeout(timer)
        var _this = this
        var _arguments = arguments
        timer = setTimeout(function() {
          func.apply(_this, _arguments)
        }, delay)
      }
    }
ES6语法
 function bar(c, d) {
      console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      setTimeout(() => {
        console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
        console.log(event);//undefined
      }, 500)
    }

    window.onload = function() {
      bar(22, 33)
    }
处理方法:
 function bar(c, d) {
      console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
      console.log(event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      var _event = event;
      setTimeout(() => {
        console.log(arguments);//Arguments(2) [22, 33, callee: ƒ, Symbol(Symbol.iterator): ƒ]
        console.log(_event);//Event {isTrusted: true, type: "load", target: document, currentTarget: Window, eventPhase: 2, …}
      }, 500)
    }

    window.onload = function() {
      bar(22, 33)
    }

最终的基于ES6语法的防抖函数【这里有疑问?????】:

function debounce(func, delay = 0) {
      let timer = null;
      return function (...arg) {
        clearTimeout(timer);
        timer = setTimeout(() => {
          func.apply(this, arg)
        }, delay)
      }
    }

2.节流函数

节流就是事件的触发必须在指定时间间隔之上生效,比如,间隔1s,触发后在1s内再次触发是无效的;

ES5实现:

function throttle(func, interval) {
      var last = 0

      return function() {
        var _this = this;
        var _arguments = arguments;

        var now = new Date().getTime();
        if(now - last > interval) {
          func.apply(_this, _arguments)
          last = now
        }
      }
    }

ES6实现:

思路:
1.事件触发,执行函数,在间隔时间到之前,再次触发函数时,timer不为空,因此不会执行if后面的代码;
2.只有在间隔时间到了之后,在回调函数中将timer置空,从而可以实现节流的效果;

function throttle(func, interval) {
      let timer = null;

      return function(...args) {
        if (!timer) {
          timer = setTimeout(() => {
            timer = null;
            func.apply(this, args)
          }, interval)
        }
      }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。