防抖前面已經用過,但沒有研究具體代碼,因爲用到閉包,call,apply就一起看下了。
我試過這篇文章裏的防抖
防抖
Tips
注意debounce函數的使用,如果直接在函數上調用,肯定是不行的。比如
<input type=“text” onkeyup="debounce(change, 1000)()"/>
這樣的話是不起作用的,相當於每次keyup都出發一次debounce,然後都會重新定義timer,因爲debounce返回的是函數,在加()是調用函數,這時候clearTimeout()起不到作用,也就起不到作用。
正確的使用方法應該是。先定義debounce返回的函數,然後在調用這個函數,如下
html
<input type="text" onkeyup=“refresh()”
js
let refresh = debounce(change,1000)
這樣相當於在定義refresh的時候只定義了一次timer但是每次調用的時候會判斷timer的存在,存在則會清除之前的定時器,也就不會執行change函數,如果時間沒到delay的時候繼續輸入,這時候調用函數就會執行清除定時器操作清除定時器。如果超過這個時間沒有繼續操作,那麼延時器內的操作函數就會執行。
這裏用到閉包的作用是避免在全局內定義一個定時器來佔用全局空間,如果在全局定義一個變量的話,我們可以直接使用debounce裏return出來的函數就可以了,閉包的作用只是爲了定義一個函數內的變量,但是在每次調用時還能讀取到這個變量。相當於在多次函數的調用之間產生了聯繫。apply的作用只是爲了傳遞上下文,將參數和返回函數的參數以及this指向等統一,相當於我們在調用debounce產生的函數時不用考慮參數上下文會出現偏差。
閉包
閉包是將函數作爲返回值,實際上也只是返回函數的定義,不會調用。但是可以讀取函數內部的變量。
調用f1(), f2(), f3() 不是返回 1, 4, 9. 實際返回的是都是16。這個是先返回,後再執行。返回的是i值,最後i爲4
Call和Apply
call和apply是爲了改變上下文存在的函數
實際上也就是改變函數this的指向,將參數引入。
它們的共同之處:
都“可以用來代替另一個對象調用一個方法,將一個函數的對象上下文從初始的上下文改變爲由thisObj指定的新對象”。
即對象是括號內的第一個對象,方法是我們所寫的對象的方法
它們的不同之處:
apply:最多只能有兩個參數——新this對象和一個數組argArray。如果給該方法傳遞多個參數,則把參數都寫進這個數組裏面,當然,即使只有一個參數,也要寫進數組裏。
call:它可以接受多個參數,第一個參數與apply一樣,後面則是一串參數列表。
實際上,apply和call的功能是一樣的,只是傳入的參數列表形式不同。