通过防抖功能对js闭包的理解

以前一直对js的闭包不是很理解,看了很多文章也理解不了,果然我是个辣鸡前端,直到最近在看防抖,网上很多防抖的方法都一样,现在以滚动为例子:

// 防抖
function debounce(f, wait) {    
    var timer = null;    
    return function() {        
        if(timer !== null)   clearTimeout(timer);        
        timer = setTimeout(f, wait);    
    }
}
// 滚动后处理函数
function handle() {    
    console.log('滚动后执行的代码逻辑' + Math.random()); 
}
// 绑定滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

防抖的原理是:先设置一个定时器变量,用闭包保存,在事件触发的时候,清除定时器,然后再设置一个,那么如果页面一直滚动,刚刚建立的定时器就会被清除,直到最后不再滚动页面,就执行最后一次设置的定时器。

然后,之前一直不是很理解闭包的我更加不理解防抖原理,这是我的错误理解:每次滚动每次都调用了debounce,那定时器也被重新定义了,上一次的定时器怎么处理,怎么实现的上一次的定时器被清空,为什么为什么。。。。。

太难受了,又重新去看闭包的文章,醍醐灌顶!!!

滚动事件绑定的实际上是debounce函数return的那个匿名函数,就是个闭包,实现了对变量timer的静态化(每次调用都可以引用到之前的timer),和局部化(避免了对全局命名空间的污染),所以才能实现清空上次定时器防抖的功能。

那么闭包是怎么定义的,大多数就是一句话:有权访问另一个函数作用域内变量的函数都是闭包。举个栗子:

function test(){
  var count = 0;
  function counter(){
    count++; 
    console.log(count);
  }
  return counter;
}
var someCount = test();
someCount(); 
someCount(); 

这里打印出来的分别是1、2,
var someCount = test()这一句中,test()返回的是counter,可以这么理解someCount = counter;(只是这么理解,并不能这么用!)
那么someCount()相当于counter();( ()是执行函数的意思
所以,变量count并没有被清掉,每次调用返回的都是叠加后的值。

总结:上面提到过的,闭包实现了对变量的静态化和局部化

(个人理解,如有错误,感谢指正!)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容