赞
踩
目录
关于节流/防抖函数中 context(this) 的指向解析:
我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove, resize, onscroll等等,有些时候,我们并不能或者不想频繁触发事件,咋办呢?这时候就应该用到函数防抖和函数节流了!
防抖(debounce)是指在一定时间内,只执行最后一次触发的事件。它适用于那些在连续触发事件的过程中,只关心最后一次触发的结果的情况。
例如,当用户连续输入搜索关键字时,我们可以使用防抖来减少网络请求的次数。在用户停止输入一段时间后,才发送网络请求进行搜索。
下面是一个简单的 JavaScript 实现防抖函数的例子:
- function debounce(func, delay) {
- let timer;
- return function() {
- clearTimeout(timer);
- timer = setTimeout(() => {
- func.apply(this, arguments);
- }, delay);
- };
- }
这个 debounce 函数接受两个参数:func 是要执行的函数,delay 是延迟的时间。在每次触发事件时,它会清除之前设置的定时器,并重新设置一个新的定时器。如果在延迟时间内再次触发事件,定时器会被清除并重新设置。只有在延迟时间结束后没有再次触发事件,才会执行函数。
节流(throttle)是指在一定时间内,固定执行事件的频率。它适用于那些在连续触发事件的过程中,需要保持一定的执行频率的情况。
例如,当用户持续滚动页面时,我们可以使用节流来限制处理滚动事件的频率,以避免过多的计算和渲染。
下面是一个简单的 JavaScript 实现节流函数的例子:
- function throttle(func, delay) {
- let timer;
- return function() {
- if (!timer) {
- timer = setTimeout(() => {
- func.apply(this, arguments);
- timer = null;
- }, delay);
- }
- };
- }
这个 throttle 函数接受两个参数:func 是要执行的函数,delay 是延迟的时间。在每次触发事件时,它会检查是否存在定时器,如果不存在则设置一个新的定时器,并在延迟时间结束后执行函数。这样可以保证在延迟时间内只执行一次函数。
总结起来,防抖和节流都是用于优化性能和控制事件触发频率的技术。防抖适用于只关心最后一次触发结果的情况,而节流适用于需要保持一定执行频率的情况。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title></title>
- <style>
- body {
- height: 200vh;
- /* 为了触发滚动事件,增加页面高度 */
- }
- </style>
- </head>
- <body>
- <h1>防抖和节流示例</h1>
-
- <script>
- // 防抖函数
- function debounce(func, delay) {
- let timer; // 定时器变量
- return function() {
- clearTimeout(timer); // 清除之前的定时器
- timer = setTimeout(() => {
- func.apply(this, arguments); // 延迟时间结束后执行函数
- }, delay);
- };
- }
-
- // 节流函数
- function throttle(func, delay) {
- let timer; // 定时器变量
- return function() {
- if (!timer) {
- timer = setTimeout(() => {
- func.apply(this, arguments); // 延迟时间结束后执行函数
- timer = null; // 清空定时器变量
- }, delay);
- }
- };
- }
-
- // 示例函数:处理滚动事件
- function handleScroll() {
- console.log("处理滚动事件");
- }
-
- // 使用防抖函数包装处理滚动事件的函数
- const debouncedHandleScroll = debounce(handleScroll, 200);
-
- // 使用节流函数包装处理滚动事件的函数
- const throttledHandleScroll = throttle(handleScroll, 200);
-
- // 监听滚动事件,并调用相应的处理函数
- window.addEventListener("scroll", debouncedHandleScroll);
- // 如果要使用节流函数,可以将上面一行改为下面这行
- // window.addEventListener("scroll", throttledHandleScroll);
- </script>
- </body>
- </html>
在防抖和节流函数中,this 的指向非常重要。下面分别解析一下:
在防抖函数中,如果不加以处理,this 会指向当前调用防抖函数的对象(例如 window 对象)。因此,我们需要使用 Function.prototype.apply() 或 Function.prototype.call() 方法来明确指定 this 的值。
例如,以下代码中的 handleInput 函数在执行时,this 会指向 input 元素本身:
<input type="text" oninput="debouncedHandleInput.call(this, event)">
这里的 this 表示当前的 input 元素。通过 call() 方法将 this 明确指定为 debouncedHandleInput 函数中的 this。
在节流函数中,this 的指向与防抖函数略有不同。在节流函数中,this 通常应该指向事件的目标元素(例如 button 元素),而不是当前调用节流函数的对象(例如 window 对象)。
例如,以下代码中的 handleClick 函数在执行时,this 会指向 button 元素本身:
<button onclick="throttledHandleClick(event)">点击</button>
这里的 this 表示当前的 button 元素。在 throttledHandleClick 函数中,可以使用 this 来获取目标元素的属性、修改样式等操作。
需要注意的是,在使用箭头函数定义防抖和节流函数时,this 的指向不会改变,仍然指向外层作用域的 this。
综上所述,防抖和节流函数中的 this 指向应该根据实际情况进行明确指定。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。