📖JavaScript专栏:📑js实用技巧篇
👊👊👊该专栏博主会持续更新,目的是给大家分享一些非常实用的技巧,同时巩固自己的基础,共同进步✨✨✨
💡💡💡欢迎大家在评论区留言交流技术以及学习方法、心得方面的问题。💡💡💡
👇🏻👇🏻👇🏻你的一键三连是对我的最大支持❤️❤️❤️
🌟🌟🌟祝大家国庆快乐!!!🌟🌟🌟
📑前言
本专栏主要是一些实用技巧,带大家灵活运用、并理解其思想;另外后续也会开设js核心知识方面的专栏带大家深入理解js这门语言。由于个人刚完成js阶段的学习,却没有什么项目经验,另外感觉自己基础也不是很好;所以梳理了下js学习过程中个人认为必须掌握的一些知识点、技巧等,以此为后期的学习打下坚实的基础。
📑函数防抖|节流
本篇主要讲解函数防抖、节流的实现及其原理,并通过应用场景带大家更直观地理解
📃函数防抖
先来看看实际开发中经常用到函数防抖场景:input对话框的input事件监听
无函数防抖效果1:
代码1:
有函数防抖效果2:
代码2:
通过上面有无函数防抖的对比,可以看出防抖函数的作用,接下来就带大家使用并理解其原理
防抖函数的实现如下:
/**
* @param {Function} fn 需要延迟执行的函数
* @param {Number} delay 函数fn延迟执行的时间
* @returns 返回一个函数,在delay时间过后执行该函数; 如果某事件再次被触发,清除前一个计时器,即前一次在delay时间过后要执行的函数被清除,然后再次返回该函数;即每触发防抖函数,都会重新返回一个新的在delay时间过后要执行的函数
*/
function debounce(fn, delay = 1000) {
let timerId;//声明一个计时ID
return function () {
clearTimeout(timerId);//清除前面的计时ID
timerId = setTimeout(() => fn.call(this, ...arguments), delay);
};
}
函数防抖:
- 让某个函数的执行推迟,如果在推迟期间执行函数,会将函数进一步推迟
- 当用户多次触发某事件时,会造成频繁向后端服务器发送请求
- 为了避免这种情况,函数防抖保证只在最后一次触发后执行函数,也就是只向后台发送最后一次的请求
debounce函数部分讲解:
-
arguments
是用来存放传递给函数的参数的一个伪数组,它是所有(非箭头)函数中都可用的局部变量(引用MDN官方的原话),...arguments
用到了ES6中的展开运算符...
,即将该伪数组展开;则上面等效于fn.call(this,arg1,arg2...)
-
此处的
fn.call(this, ...arguments)
也可用fn.apply(this,arguments)
替换,此处的.call()
和.apply()
两个都是Function
的原型方法,功能相同,传参方式不同;call
是传参数列表,而apply
传的是数组,而其中的this
是调用call
和apply
函数的新this
,即此时调用call
和apply
方法的函数的this
为call
和apply
中的第一个参数,本人解释的可能不太清楚,可以查询官方文档call()、apply()相关解释。
关于this
绑定上面说的可能有点绕,来看看下面这个实例演示,此处创建了一个父构造函数和两个子构造函数:
function Animal(name) {
this.name = name;
}
function Fish(name, ability) {
Animal.call(this, name);//此处等同于 this.name = name;
this.ability = ability;
}
function Dog(name, ability) {
Animal.call(this, name);//此处等同于 this.name = name;
this.ability = ability;
}
var fish1 = new Fish("小鱼", "游得快");
var dog1 = new Dog("小狗", "跑得快");
console.log(fish1, dog1);
输出:
📃函数节流
关于函数节流有两种版本,代码实现如下:
//时间戳,开始阶段就会触发
function throttle(fn, wait) {
let previous = 0; //相当于任务开始时间
return function () {
let now = Date.now(); //获取当前时间戳
if (now - previous > wait) {
fn.apply(this, arguments);
previous = now;
}
};
}
//计时器,结束阶段触发
function throttle(fn, wait) {
let timerId; //声明计时器ID
return function () {
if (!timerId) {
timerId = setTimeout(() => {
timerId = null;
fn.apply(this, arguments);
}, wait);
}
};
}
虽然函数节流的场景(例如滚动条滚动时函数的处理,可以通过节流适当减少响应次数)不是下面所举的例子,但我们主要通过其来看出差别,所以此处依旧通过监听文本框的输入来探讨函数节流两种版本的区别
时间戳版本:
不难发现在初始时就触发了一次,随后每隔2s触发一次,函数节流与函数防抖的区别就很明显了,对函数节流而言,在设定的时间内一定会执行一次,而函数防抖是在最后一次触发后才执行。
实现代码:
计时器版本:
由上可知,计时器版本的函数节流是在每2s的最后阶段才会触发,这就是二者的区别。
实现代码:
📑总结
函数防抖和节流:
- 目的:都是为了节约计算机资源,提升用户体验
- 节流:在指定时间间隔内只会执行一次任务
- 防抖:当任务频繁触发的情况下,只有任务触发的间隔超过指定时间间隔的时候(即最后一次触发任务后,不再触发该任务,然后在指定时间间隔过后),任务才会执行