JS实现,防抖&节流 + 闭包

防抖(Debounce)

防抖是指短时间内大量触发同一事件,只会在最后一次事件完成后延迟执行一次函数。

防抖的典型应用场景是输入框的搜索建议功能,用户输入时不需要每次输入都去查询,而是在用户停止输入一段时间后才进行查询。

function debounce(fn, delay) {
        let timer = null
        return function (...args) {
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                        timer = null
                        fn.apply(this, args)
                }, (delay + '') | 0 || 1000 / 60)
        }
}

  • 为什么每次调用这个函数的时候,timer都是同一个?
    涉及到了闭包的概念,使得返回的函数能够持续访问和修改 timer 变量,这是实现防抖功能的关键。
  • …args是什么
    称为“rest参数”(rest parameters)
    注意:① …args 会将所有传入的参数收集到一个名为 args 的数组中。② 这个数组包含了所有传递给函数的参数,无论传入多少个参数。
  • this
    this 是一个关键字,它指向函数执行时的上下文对象。
    在这里插入图片描述
  • 在 JavaScript 中,apply 函数是存在的,它是 Function 对象的一个方法。apply 允许你调用一个函数,并指定函数的 this 值,同时传递一个参数数组给函数。
  • delay

(delay + '') | 0 || 1000 / 60
delay + ‘’:这部分将 delay 转换为字符串(通过隐式类型转换)。如果 delay 已经是一个数字,这个操作不会改变它的值,但如果 delay 是其他类型(如字符串或 null),它将被转换为字符串。
| 0:这是一个按位或操作,它将字符串转换为一个整数。在 JavaScript 中,任何与 0 进行按位或操作的字符串都会被转换为该字符串的数值表示(如果可能)。如果字符串不是一个有效的数字,结果将是 0。
|| 是逻辑或操作符。如果前面的表达式((delay + ‘’) | 0)的结果是 0 或 null 或 undefined 或任何其他假值,那么逻辑或操作符将评估并返回后面的表达式(1000 / 60)。

节流(Throttle)

节流是指在指定的时间间隔内,只允许函数执行一次,不管事件触发了多少次。这可以确保在给定的时间间隔内,函数只执行一次。

function throttle(fn, interval) {
        let timer = null
        return function (...args) {
                if (timer) return
                timer = setTimeout(() => {
                        timer = null
                        fn.apply(this, args)
                }, (interval +'')| 0 || 1000 / 60)
        }
}

防抖&节流中的this

在 JavaScript 中,this 是一个关键字,它指向函数执行时的上下文对象。函数的 this 值是在调用时确定的,而不是在定义时确定的。这意味着同一个函数在不同的调用方式下,this 的值可能不同。

在 JavaScript 中,函数可以作为一个对象的方法被调用,这时 this 会指向那个对象。例如:

const obj = {
  myMethod: function() {
    console.log(this);
  }
};

obj.myMethod(); // 输出 obj 对象

在 debounce 函数中,this 的使用是为了确保当返回的函数被调用时,它能够保持与原始函数 fn 相同的上下文。这通常是为了让 fn 能够访问到它被调用时的对象。

const obj = {
  value: 42,
  getValue: function() {
    console.log(this.value);
  }
};

const debouncedGetValue = debounce(obj.getValue, 300);

// 假设我们通过事件监听器调用 debouncedGetValue
document.addEventListener('click', debouncedGetValue);

闭包 closure

闭包=内层函数+引用的外层函数变量

function createCounter() {
  let count = 0;
  return function() {
    count += 1;
    console.log(count);
  };
}

const counter = createCounter();
counter(); // 输出 1
counter(); // 输出 2

在这个例子中,createCounter 函数创建了一个局部变量 count 和一个内部函数。内部函数访问并修改了 count 变量。当 createCounter 函数执行完毕后,通常 count 变量应该被垃圾回收。但由于返回的内部函数形成了一个闭包,它仍然保持着对 count 变量的引用,因此 count 变量不会被回收,直到闭包被销毁。

应用

  • 闭包的形式-统计函数调用的次数

不是闭包的写法:(i属于全局变量,如果在全局修改之后会有问题)

let i=0
function fn() {
  i++
  console.log(`函数被调用了${i}`)
}

闭包写法,实现数据私有

function count() {
	let i=0
	function fn() {
	  i++
	  console.log(`函数被调用了${i}`)
	}
	return fn
}

const res = count()
res() // 1
res() // 2

问题-内存泄漏

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值