变量作用域
我们知道,JavaScript
里变量是从内到外,逐层寻找变量。
var count = 0;
function counter(){
count++;
console.log(count);
}
如果未找到,则是一个undefined
。
这是JavaScript
变量作用域的特性,而闭包
则是利用这个特性。
所以,上面这段代码,其实就是闭包
。
闭包
上面的代码,就是闭包
,但是并不符合我们的使用需求。
没人希望count
可以被随意改动,因为它是一个全局变量。
所以,我们必须把它隐藏起来。
如何隐藏?答案就是把它放进function
里面。
function counter(){
var count = 0;
}
就是这么简单,count
被隐藏进入方法里面了,或者说count
被包起来了,所以才用闭包
来形容。
但是,这个时候,想使用count
变量,怎么办?
这就要求闭包
方法,必须对外暴露一个接口
:
function counter(){
var count = 0;
return function(){
count++;
console.log(count);
}
}
var c = counter();
c();
c();
这样,count
就仅限于接口
访问了,而这个,就是你熟悉的闭包
了。
防抖
在实际开发中,会有如下场景:
- 滚动触发频繁
- input onkeyup 触发频繁
- vue组件重新渲染,多次mounted
等等这些场景,都需要限制方法执行频率。
利用闭包
& setTimeout
我们有了这样一个解决方案。
function debounce(fn,delay){
var timer = null;
return function(){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(fn,delay);
}
}
function test(){
console.log(123)
}
var r = debounce(test,1000)
r();
r();
如果你运行了代码,会发现只打印了1个123
,这说明,防抖成功了。