在上一篇中我总结了节流函数和防抖函数的基本原理:总结前端函数防抖与函数节流
接下来介绍一下防抖函数和节流函数在前端框架中的使用。

在使用前一定要注意两个问题:

  • this的指向
  • 事件对象的传递

React中使用防抖函数和节流函数

在React事件调用时,React传递给事件处理程序是一个合成事件对象的实例。SyntheticEvent对象是通过合并得到的。 这意味着在事件回调被调用后,SyntheticEvent 对象将被重用并且所有属性都将被取消。 这是出于性能原因。 因此,您无法以异步方式访问该事件
React合成事件官方文档

//React无法异步访问事件对象
function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  const eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  // 不能工作。 this.state.click 事件只包含空值。
  this.setState({clickEvent: event});

  // 您仍然可以导出事件属性。
  this.setState({eventType: event.type});
}

所以在用防抖或节流函数封装时,异步方式访问事件对象出现问题。解决的方法如下:

  • 方法一:调用合成事件对象的persist()方法
  • 方法二:深拷贝事件对象
function debounce(func, wait=500) {
    let timeout;  // 定时器变量
    return function(event){
        clearTimeout(timeout);  // 每次触发时先清除上一次的定时器,然后重新计时
        event.persist && event.persist()   //保留对事件的引用
        //const event = e && {...e}   //深拷贝事件对象
        timeout = setTimeout(()=>{
            func(event)
        }, wait);  // 指定 xx ms 后触发真正想进行的操作 handler
    };
}

class Test extends React.Component{
    handleChange = debounce((e)=>{
        console.log(e.type)
        console.log(this)
    })
    render(){
        return (
            <div>
                <input type="text" onChange={this.handleChange}/>
            </div>
        )
    }
}

在这里插入图片描述

在Vue中使用防抖函数和节流函数

<div id="app">
    <input type="text" @keydown="handleChange">
</div>

<script>
function debounce(func, wait=500) {
   let timeout;  // 定时器变量
    return function(event) {
        clearTimeout(timeout);  // 每次触发时先清除上一次的定时器,然后重新计时
        timeout = setTimeout(()=>{
            console.log(123,this)
            func.call(this,event)
        }, wait);  // 指定 xx ms 后触发真正想进行的操作 handler
    };
}
new Vue({
    el: '#app',
    methods: {
        handleChange:debounce(function(e){
            console.log(e)
            console.log(this)
        })
    }
})
</script>

在这里插入图片描述

在小程序中使用防抖函数和节流函数

<input bindinput='change' style='border:1px solid #000;'></input>

function debounce(func, wait = 500) {
  let timeout;
  return function (event) {
    clearTimeout(timeout); 
    timeout = setTimeout(() => {
      func.call(this, event)
    }, wait);  
  };
}

Page({
  change: debounce(function(e){
    console.log(e)
    console.log(this)
  })
})

在这里插入图片描述

总结

上面this的指向涉及了复杂的知识点:箭头函数、闭包、class方法的this、事件调用、call等。单个理解这些知识点并不是很难,但是组合在一起后,理解就很困难了。目前自己对上面框架中防抖函数的this指向还不清楚,自己只是在代码中试错来理解this。

Logo

前往低代码交流专区

更多推荐