今天我們來搞一搞節(jié)流秧秉,防抖褐桌,柯里化和反柯里化吧,是不是一看這詞就覺得哎喲wc象迎,有點(diǎn)高大上啊荧嵌。事實(shí)上,我們可以在不經(jīng)意間用過他們但是你卻不知道他們叫什么砾淌,沒關(guān)系啦撮,相信看了今天的文章你會有一些收獲的
節(jié)流
首先我們來搞一下節(jié)流,啥叫節(jié)流汪厨,就是將高頻率觸發(fā)事件變成低頻率觸發(fā)事件赃春,舉個簡單的例子,但我們用window.onscroll滾動事件的時候你會發(fā)現(xiàn)滾輪滑動一次可能會觸發(fā)好多次事件劫乱,
代碼:
window.onscroll = function(){
console.log("觸發(fā)")
}
結(jié)果:
我只是稍微滑動了一下子而已织中,就觸發(fā)了十次,這個觸發(fā)次數(shù)實(shí)在是過于頻繁衷戈,那我們有沒有什么方法來解決這個問題呢狭吼?
思路:我們可以給一個開關(guān),用定時器控制開關(guān)的變化殖妇,只有當(dāng)開關(guān)打開時我們才去觸發(fā)打印刁笙。
核心代碼:
var bStop = true;
window.onscroll = function() {
if(!bStop){
return;
}
bStop = false;
setTimeout(()=>{
var t = document.documentElement.scrollTop || document.body.scrollTop;
console.log(t);
bStop = true;
},300)
}
原諒我直接給你們把代碼放上來了,你們就不用一句一句打了谦趣,直接拉下代碼去就可以run了疲吸,美滋滋啊
適用場景:
1.onscroll()
2.onresize()
3.oninput()
等等
防抖
現(xiàn)在我們再來看一看防抖,簡單來說蔚润,防抖就是不關(guān)心中間過程磅氨,只關(guān)心最后的結(jié)果
例如在滾動時,我們需要獲取滾動結(jié)束時的位置嫡纠,此時我們并不關(guān)心滾動過程中發(fā)生了什么烦租,而僅僅只是想知道結(jié)束那一刻的狀態(tài),那這個時候我們就可以用到防抖
思路:在執(zhí)行函數(shù)時先清除一個延時器除盏,之后再創(chuàng)建一個延時器叉橱,這樣每次函數(shù)觸發(fā)都會將上一個延時器清除并且建立下一個延時器,中間過程的延時器根本不會被觸發(fā)者蠕,因?yàn)樗麆倓?chuàng)建好就被清除了窃祝,只有最后一個延時器,由于沒有人來清除他踱侣,所以他會正常執(zhí)行粪小。
可能我說的不是很透徹大磺,沒關(guān)系,讓我直接上代碼好吧探膊,代碼還是很簡潔清晰的
核心代碼:
var timer = null;
window.onscroll = function(){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(()=>{
var t = document.documentElement.scrollTop || document.body.scrollTop;
console.log(t);
},300)
}
柯里化
接著我們來搞一搞柯里化好吧杠愧,柯里化是指將使用多個參數(shù)的函數(shù)轉(zhuǎn)換成一系列使用一個參數(shù)的函數(shù)的技術(shù)(又稱為部分求值),
目的:為了縮小適用范圍逞壁,創(chuàng)建一個針對性更強(qiáng)的函數(shù)
特點(diǎn):
1.提高了代碼的合理性流济,更重的它突出一種思想---降低適用范圍,提高針對性腌闯。
2.對于一個已有函數(shù)绳瘟,對其約定好其中的某些參數(shù)輸入,然后生成一個更有好的姿骏、更符合業(yè)務(wù)邏輯的函數(shù)糖声。
好處:
1.提高針對性
2.延遲執(zhí)行(只有在最后一次才執(zhí)行)
3.固定易變因素
現(xiàn)在我們直接上一個小小的例子,有一個廚師工腋,要做飯姨丈,但是他的手下沒有把菜買齊,這樣擅腰,買一份原料蟋恬,放在廚師廚房,再買一份趁冈,放在廚師廚房歼争,等買齊了,叫廚師過來渗勘,好了沐绒,原料齊了,可以做飯了旺坠。這個時候乔遮,廚師利用原料,把飯做好取刃。廚師就像一個函數(shù)蹋肮,他有自己的功能(做飯),但是參數(shù)(原料)不齊璧疗,每次執(zhí)行這個函數(shù)坯辩,在參數(shù)不齊的情況下,只能返回一個新的函數(shù)崩侠,這個新的函數(shù)已經(jīng)內(nèi)置了之前的參數(shù)漆魔,當(dāng)參數(shù)齊了之后完成他本身的功能。
舉一個柯里化的小栗子,假設(shè)現(xiàn)在我們要按照柯里化的思想實(shí)現(xiàn) add(1,2,3)(1)(2)(3)(4,5,6)(7,8)() 對里面所有的參數(shù)求和
直接上代碼好吧
// add 函數(shù)柯里化
function add(){
//建立args,利用閉包特性改抡,不斷保存arguments
var args = [].slice.call(arguments);
//方法一矢炼,新建_add函數(shù)實(shí)現(xiàn)柯里化
var _add = function(){
if(arguments.length === 0){
//參數(shù)為空,對args執(zhí)行加法
return args.reduce(function(a,b){return a+b});
}else {
//否則阿纤,保存參數(shù)到args裸删,返回一個函數(shù)
[].push.apply(args,arguments);
return _add;
}
}
//返回_add函數(shù)
return _add;
思想:
1.當(dāng)參數(shù)的長度不為0時,存儲參數(shù)阵赠,
2.當(dāng)參數(shù)的長度為零時,計算所有參數(shù)的和
反柯里化
作用:在與擴(kuò)大函數(shù)的適用性肌稻,使本來作為特定對象所擁有的功能的函數(shù)可以被任意對象所用.
對反柯里化更通俗的解釋可以是 函數(shù)的借用清蚀,是函數(shù)能夠接受處理其他對象,通過借用泛化爹谭、擴(kuò)大了函數(shù)的使用范圍枷邪。
下面放一個通用的柯里化函數(shù):
var uncurrying= function (fn) {
return function () {
var args=[].slice.call(arguments,1);
return fn.apply(arguments[0],args);
}
};