热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

手写防抖和节流中的一些细节

使用函数节流与函数防抖的目的,就是为了节约计算机资源,提升用户体验。js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输

使用函数节流与函数防抖的目的,就是为了节约计算机资源,提升用户体验。js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。

防抖:短时间内大量触发,但只执行一次。原理:设置定时器,delay时间后执行事件处理,期间每次触发事件都会将定时器重置,直到delay时间内无第二次事件触发。

function debounce (func, delay) {
let task = null
return function (...args) {
if (task) {
clearTimeout(task)
}
task = setTimeout(() => {
func.apply(this, ...args)
}, delay)
}
}
// 使用
let debounceFunc = debounce(scrollEvent, 300)
document.getElementById("my_input").addEventListener("keydown", function () {
debounceFunc(456)
})
function scrollEvent(args) {
console.log("滚动" + args);//滚动456
}

节流:隔一段时间执行一次,期间被多次触发也不管。实现原理:设置定时器,delay时间后执行事件处理,当事件执行完后清除定时器。

function throttle (func, delay) {
let task = null
return function (...args) {
if (!task) {
task = setTimeout (() => {
task = null
func.apply(this, ...args)
}, delay)
}
}
}
// 使用
let throttleFunc = throttle(scrollEvent, 300)
document.addEventListener("scroll", function () {
throttleFunc(123)
})
function scrollEvent(args) {
console.log("滚动" + args);
}

对于两函数中的func.apply(this, ...args),之前感觉一直没弄清楚,于是查了很多资料,以下是自己的分析。

知识点详解:

1.定时器回调函数中的this指向问题:

(1)如果没有特殊指向,setInterval和setTimeout的回调函数中this的指向都是window。这是因为JS的定时器方法是定义在window下的。

(2)call,apply,bind可以修改this指向

(3)箭头函数没有自己的this,它的this继承自外部函数的作用域。

因此上面代码setTimeout中的this继承外层匿名函数的this,也就是节流和防抖函数的调用者。

2.apply方法的使用

Function.apply(obj,args)可将函数的this对象指向obj,args则为函数的输入参数,以数组形式传入。

上面代码中func.apply(this, ...args)则是将func的this指向改为setTimeout中的this,也就是将func的this指向改为节流和防抖函数的调用者。

上文所写的节流和防抖函数的返回值是一个函数,因此在调用时可以给其传参,输入参数可以使用剩余参数语法function (...args)写入返回的匿名函数中,并利用func.apply(this, ...args)的第二个参数传给func。



推荐阅读
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • Python中的PyInputPlus模块原文:https ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • 前段时间做一个项目,需求是对每个视频添加预览图,这个问题最终选择方案是:用canvas.toDataYRL();来做转换获取视频的一个截图,添加到页面中,达到自动添加预览图的目的。 ... [详细]
author-avatar
chung
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有