以前一直對js的閉包不是很理解慰技,看了很多文章也理解不了椭盏,果然我是個辣雞前端,直到最近在看防抖吻商,網(wǎng)上很多防抖的方法都一樣掏颊,現(xiàn)在以滾動為例子:
// 防抖
function debounce(f, wait) {
var timer = null;
return function() {
if(timer !== null) clearTimeout(timer);
timer = setTimeout(f, wait);
}
}
// 滾動后處理函數(shù)
function handle() {
console.log('滾動后執(zhí)行的代碼邏輯' + Math.random());
}
// 綁定滾動事件
window.addEventListener('scroll', debounce(handle, 1000));
防抖的原理是:先設(shè)置一個定時器變量,用閉包保存,在事件觸發(fā)的時候乌叶,清除定時器盆偿,然后再設(shè)置一個,那么如果頁面一直滾動准浴,剛剛建立的定時器就會被清除事扭,直到最后不再滾動頁面,就執(zhí)行最后一次設(shè)置的定時器乐横。
然后求橄,之前一直不是很理解閉包的我更加不理解防抖原理,這是我的錯誤理解:每次滾動每次都調(diào)用了debounce葡公,那定時器也被重新定義了罐农,上一次的定時器怎么處理,怎么實現(xiàn)的上一次的定時器被清空匾南,為什么為什么啃匿。。蛆楞。溯乒。。
太難受了豹爹,又重新去看閉包的文章裆悄,醍醐灌頂!1哿光稼!
滾動事件綁定的實際上是debounce函數(shù)return的那個匿名函數(shù),就是個閉包孩等,實現(xiàn)了對變量timer的靜態(tài)化(每次調(diào)用都可以引用到之前的timer)艾君,和局部化(避免了對全局命名空間的污染),所以才能實現(xiàn)清空上次定時器防抖的功能肄方。
那么閉包是怎么定義的冰垄,大多數(shù)就是一句話:有權(quán)訪問另一個函數(shù)作用域內(nèi)變量的函數(shù)都是閉包。舉個栗子:
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蝴罪;(只是這么理解,并不能這么用2角濉)
那么someCount()相當于counter()要门;( ()是執(zhí)行函數(shù)的意思 )
所以,變量count并沒有被清掉,每次調(diào)用返回的都是疊加后的值暂衡。
總結(jié):上面提到過的询微,閉包實現(xiàn)了對變量的靜態(tài)化和局部化。
(個人理解狂巢,如有錯誤撑毛,感謝指正!)