前言
本文1012字,閱讀大約須要4分鐘。前端
總括: 本文經過實例介紹了什麼是節流函數,什麼是防抖函數。app
- 公衆號:「前端進階學習」,回覆「666」,獲取一攬子前端技術書籍
社會猶如一條船,每一個人都要有掌舵的準備。函數
正文
節流函數和防抖函數相信不少人都在平常業務開發中使用過,其實無論是節流函數仍是防抖函數都是一種簡單的高階函數,他們都是經過將一個關鍵的外部變量保存在外層做用域,經過對這個變量的判斷和操做來決定是否調用回調函數。學習
節流函數
函數節流讓指函數有規律的進行調用,應用場景:測試
- 遊戲中發射子彈的頻率(好比1秒發射一顆);
- 滾動事件;
所謂節流即讓回調函數在必定時間內只能調用一次,所以咱們的節流函數須要的參數有兩個:this
- 回調函數;
- 延遲執行的時間;
實現以下:rest
/** * @param {function} fun 調用函數 * @param {number} delay 延遲調用時間 * @param {array} args 剩餘參數 */ const throttle = (fun, delay, ...args) => { let last = null; return (...rest) => { const now = + new Date(); let _args = [...args, ...rest]; if (now - last > delay) { fun.apply(null, _args); last = now; } } }
解釋下上面的代碼,咱們經過在外層函數聲明一個last
變量,而後返回一個函數,在該函數中獲取當前的時間,拼接外層函數的剩餘參數和內層函數的參數,若是當前的時間戳和上一次調用的時間戳差大於延遲時間,那麼就執行回調函數。咱們測試下:code
var obj = { a: 1 }; var num = 0; //實例 var throttleExample = throttle(function(...rest) { console.log(rest, this.a); num++; }.bind(obj), 1000); //調用 throttleExample(num); throttleExample(num); throttleExample(num); //
如上代碼,咱們調用了三次throttleExample
但只打印了一次[0] 1
。節流函數顧名思義就像是控制水流的函數,讓水流勻速流動的函數。也就是說在必定時間內,函數無論調用多少次,實際只執行第一次調用。遊戲
防抖函數
函數防抖讓函數在」調用’’以後的一段時間後生效,應用場景:事件
- 輸入框輸入事件;
- window.resize事件,窗口大小調整事件;
- 滾動事件;
和節流函數類似防抖函數一樣須要兩個參數:
- 回調函數;
- 延遲調用時間;
實現以下:
/** * @param {function} fun 調用函數 * @param {number} delay 延遲調用時間 * @param {array} args 剩餘參數 */ const debouce = (fun, delay, ...args) => { let timer = null; return (...rest) => { clearTimeout(timer); timer = setTimeout(() => { fun.apply(null, [...args, ...rest]); }, delay); } }
解釋下上面代碼,在外層函數聲明一個timer變量,內層函數設置定時器,在delay時間後執行該函數,並將定時器返回的標誌保存在timer裏面,在此期間一旦有調用,就取消定時器,從新開始定時。咱們測試下:
var obj = { a: 1 }; var num = 0; //實例 var debouceExample = debouce(function(...rest) { console.log(rest, this.a); num++; }.bind(obj), 1000); //調用 debouceExample(num); debouceExample(num); debouceExample(num);
如上代碼調用三次debouceExample
函數,1秒後打印一次[0] 1
。防抖函數顧名思義防止函數抖動,在必定時間內無論調用多少次,執行的都會是最後一次的調用。並且最後一次的調用時間是在必定時間以後。
結論
無論是節流函數仍是防抖函數目的都是爲了防止某個函數屢次調用形成的bug或是空間的浪費。
能力有限,水平通常,歡迎勘誤,不勝感激。
訂閱更多文章可關注公衆號「前端進階學習」,回覆「666」,獲取一攬子前端技術書籍