防抖前面已經(jīng)用過轩触,但沒有研究具體代碼,因?yàn)橛玫介]包家夺,call脱柱,apply就一起看下了。
Debounce 和 Throttle 的原理及實(shí)現(xiàn)
我試過這篇文章里的防抖
防抖
Tips
注意debounce函數(shù)的使用拉馋,如果直接在函數(shù)上調(diào)用榨为,肯定是不行的。比如
<input type=“text” onkeyup="debounce(change, 1000)()"/>
這樣的話是不起作用的煌茴,相當(dāng)于每次keyup都出發(fā)一次debounce随闺,然后都會(huì)重新定義timer,因?yàn)閐ebounce返回的是函數(shù)蔓腐,在加()是調(diào)用函數(shù)板壮,這時(shí)候clearTimeout()起不到作用,也就起不到作用合住。
正確的使用方法應(yīng)該是绰精。先定義debounce返回的函數(shù),然后在調(diào)用這個(gè)函數(shù)透葛,如下
html
<input type="text" onkeyup=“refresh()”
js
let?refresh =?debounce(change笨使,1000)
這樣相當(dāng)于在定義refresh的時(shí)候只定義了一次timer但是每次調(diào)用的時(shí)候會(huì)判斷timer的存在,存在則會(huì)清除之前的定時(shí)器,也就不會(huì)執(zhí)行change函數(shù)僚害,如果時(shí)間沒到delay的時(shí)候繼續(xù)輸入硫椰,這時(shí)候調(diào)用函數(shù)就會(huì)執(zhí)行清除定時(shí)器操作清除定時(shí)器。如果超過這個(gè)時(shí)間沒有繼續(xù)操作萨蚕,那么延時(shí)器內(nèi)的操作函數(shù)就會(huì)執(zhí)行靶草。
這里用到閉包的作用是避免在全局內(nèi)定義一個(gè)定時(shí)器來占用全局空間,如果在全局定義一個(gè)變量的話岳遥,我們可以直接使用debounce里return出來的函數(shù)就可以了奕翔,閉包的作用只是為了定義一個(gè)函數(shù)內(nèi)的變量,但是在每次調(diào)用時(shí)還能讀取到這個(gè)變量浩蓉。相當(dāng)于在多次函數(shù)的調(diào)用之間產(chǎn)生了聯(lián)系派继。apply的作用只是為了傳遞上下文,將參數(shù)和返回函數(shù)的參數(shù)以及this指向等統(tǒng)一捻艳,相當(dāng)于我們?cè)谡{(diào)用debounce產(chǎn)生的函數(shù)時(shí)不用考慮參數(shù)上下文會(huì)出現(xiàn)偏差驾窟。
閉包
閉包是將函數(shù)作為返回值,實(shí)際上也只是返回函數(shù)的定義认轨,不會(huì)調(diào)用绅络。但是可以讀取函數(shù)內(nèi)部的變量。
調(diào)用f1(), f2(), f3()?不是返回 1, 4恩急, 9.?實(shí)際返回的是都是16节视。這個(gè)是先返回,后再執(zhí)行假栓。返回的是i值寻行,最后i為4
Call和Apply
call和apply是為了改變上下文存在的函數(shù)
實(shí)際上也就是改變函數(shù)this的指向,將參數(shù)引入匾荆。
它們的共同之處:
都“可以用來代替另一個(gè)對(duì)象調(diào)用一個(gè)方法拌蜘,將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛蓆hisObj指定的新對(duì)象”。
即對(duì)象是括號(hào)內(nèi)的第一個(gè)對(duì)象牙丽,方法是我們所寫的對(duì)象的方法
它們的不同之處:
apply:最多只能有兩個(gè)參數(shù)——新this對(duì)象和一個(gè)數(shù)組argArray简卧。如果給該方法傳遞多個(gè)參數(shù),則把參數(shù)都寫進(jìn)這個(gè)數(shù)組里面烤芦,當(dāng)然举娩,即使只有一個(gè)參數(shù),也要寫進(jìn)數(shù)組里构罗。
call:它可以接受多個(gè)參數(shù)铜涉,第一個(gè)參數(shù)與apply一樣,后面則是一串參數(shù)列表遂唧。
實(shí)際上芙代,apply和call的功能是一樣的,只是傳入的參數(shù)列表形式不同盖彭。