函式防抖與函式節流(閉包例項)
阿新 • • 發佈:2022-04-13
函式防抖
/** * @function debounce 函式防抖 * @param {Function} fn 需要防抖的函式 * @param {Number} interval 間隔時間 * @return {Function} 經過防抖處理的函式 * */ function debounce(fn, interval) { let timer = null; // 定時器 return function() { // 清除上一次的定時器 clearTimeout(timer); // 拿到當前的函式作用域 let _this = this; // 拿到當前函式的引數陣列 let args = Array.prototype.slice.call(arguments, 0); // 開啟倒計時定時器 timer = setTimeout(function() { // 通過apply傳遞當前函式this,以及引數 fn.apply(_this, args); // 預設300ms執行 }, interval || 300) } }
-
概念:就是指觸發事件後在 n 秒內函式只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函式執行時間。通俗一點:在一段固定的時間內,只能觸發一次函式,在多次觸發事件時,只執行最後一次。
-
使用時機:搜尋功能,在使用者輸入結束以後才開始傳送搜尋請求,可以使用函式防抖來實現;
函式節流
/** * @function throttle 函式節流 * @param {Function} fn 需要節流的函式 * @param {Number} interval 間隔時間 * @return {Function} 經過節流處理的函式 * */ function throttle(fn, interval) { let timer = null; // 定時器 let firstTime = true; // 判斷是否是第一次執行 // 利用閉包 returnfunction() { // 拿到函式的引數陣列 let args = Array.prototype.slice.call(arguments, 0); // 拿到當前的函式作用域 let _this = this; // 如果是第一次執行的話,需要立即執行該函式 if(firstTime) { // 通過apply,綁定當前函式的作用域以及傳遞引數 fn.apply(_this, args); // 修改標識為null,釋放記憶體 firstTime = null; } // 如果當前有正在等待執行的函式則直接返回 if(timer) return; // 開啟一個倒計時定時器 timer = setTimeout(function() { // 通過apply,綁定當前函式的作用域以及傳遞引數 fn.apply(_this, args); // 清除之前的定時器 timer = null; // 預設300ms執行一次 }, interval || 300) } }
-
概念:就是限制一個函式在一定時間內只能執行一次。
-
使用時機:①改變瀏覽器視窗尺寸,可以使用函式節流,避免函式不斷執行;②滾動條scroll事件,通過函式節流,避免函式不斷執行。
函式節流與函式防抖的區別:
案例:設定一個間隔時間為一秒,在一分鐘內,不斷的移動滑鼠,讓它觸發一個函式,列印一些內容。
-
函式防抖:會列印1次,在滑鼠停止移動的一秒後列印。
-
函式節流:會列印60次,因為在一分鐘內有60秒,每秒會觸發一次。
-
總結:節流是為了限制函式的執行次數,而防抖是為了限制函式的執行時機。
函式節流與函式防抖的使用
此處使用一個物件的方法,主要為了測試this指向繫結的問題,呼叫的時候傳遞引數問題等。
function log(a,b) { console.log(a,b); console.log(this); } const throttleLog = throttle(log, 1000); const debounceLog = debounce(log, 1000); let a = { b: throttleLog, c: debounceLog }; document.body.onmousemove = function() { a.b('throttle', 'log'); a.c('debounce', 'log'); };