防抖为什么要使用闭包

1. 防抖

从概念上来讲,所谓的闭包指的是一个函数,有权访问另一个函数作用域中的变量的函数。
直观点来讲,JavaScript的闭包就是函数中嵌套函数。

<input type="text" id="input"/>
<div id="show"></div>
<script>
	function showInfo(text){
		document.getElementById('show').innerHTML=text.target.value
	}
	function debounce(func, wait) {
	    let timeout;
	    return function () {
	        let context = this;
	        let args = arguments;

	        if (timeout) clearTimeout(timeout);
	        
	        timeout = setTimeout(() => {
	            func.apply(context, args)
	        }, wait);
	    }
	}

	document.getElementById('input').addEventListener('input',debounce(showInfo,1000))
	document.getElementById('input').addEventListener('input',function(){
	document.getElementById('show').innerHTML='waiting'
		
	})
</script>

  • 问题一:能否通过将timeout变量变成全局变量来实现闭包?能
    缺点:
    1、对于一个页面上需要多个防抖函数的时候,需要写很多重复代码。
    2、全局变量污染作用域
<input type="text" id="input"/>
<div id="show"></div>

<script>
let timeout;
function delay(e) {
	if (timeout) clearTimeout(timeout);
       timeout = setTimeout(()=>{
       	showInfo(e)
       }, 1000);
}
	document.getElementById('input').addEventListener('input',delay)
	document.getElementById('input').addEventListener('input',function(){
		document.getElementById('show').innerHTML='waiting'

	})
</script>

  • 问题二:可以在函数内定义一个timeout,然后当函数执行时清除,实现防抖吗?不能
    每次事件触发后,都创建一个函数作用域内的timer变量,这样每次创建的timer变量相互不影响,且每次timer都是从undefined开始,也就不会执行clearTimeout(timer)了,不能达到防抖的目的。

本质上来讲,是因为作用域而产生一种特殊的情况,从而导致函数内部的变量无法进行销毁。这里涉及到作用域链。也是闭包产生的根本原因。

下面补充一下作用域链(Scope Chain)的知识:
从1->0
a执行完毕之后,函数链会断开,但是b执行仍然会链接上a中的变量,所以可以访问到

var global;
function a(){
	var a=123;
	function b(){
		var bb=234;
		console.log(aa);
	}
	return b;
}
var res=a();
res();

在这里插入图片描述
参考链接:作用域链

  • 总结

1、把timer变量放在内部函数中不能达到防抖的目的,因为每次执行内部的函数,都会创建一个新的timer变量。

2、用立即执行函数创造闭包可以实现防抖,是因为每次执行内部的函数,都是在操作同一个timer变量,由外部立即执行函数创建的timer变量。

3、闭包多是结合立即执行函数一起使用的,有时可能立即执行函数没有那么明显。

4、将变量timer定义为全局变量也可以达到防抖的目的,但是闭包有2个优势-

5、不用担心全局变量污染问题
6、多次调用时,相互不影响。而声明全局变量时,每次要声明不同的名字,才能不相互影响。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值