淺析JavaScript 函數(shù)柯里化
柯里化 (Currying)是把接收多個(gè)參數(shù)的原函數(shù)變換成接受一個(gè)單一參數(shù)(原來(lái)函數(shù)的第一個(gè)參數(shù)的函數(shù))并返回一個(gè)新的函數(shù),新的函數(shù)能夠接受余下的參數(shù),并返回和原函數(shù)相同的結(jié)果。
ES6的方式實(shí)現(xiàn)柯里化的通用
function currying(fn,...rest1){
return function(...rest2){
//這里用apply 是為把數(shù)組形式的參數(shù)直接傳入原函數(shù) null是因?yàn)椴恍枰淖僼his
return fn.apply(null,rest1.concat(rest2));
}
}
將一個(gè)sayHello函數(shù)柯里化
function sayHello(name,age,fruit){
console.log(`我叫${name},我${age}歲了,我喜歡吃${fruit}`);
}
//傳入第一個(gè)參數(shù)
let curryingShowMsg = currying(sayHello,'小明');
//執(zhí)行傳入剩余參數(shù)
curryingShowMsg(22,'芒果');
反柯里化 和柯里化剛好相反。為了讓方法使用場(chǎng)景更廣,使用反柯里化,可以把原生方法借出來(lái),讓任何對(duì)象擁有原生對(duì)象的方法。
二者的區(qū)別
//柯里化 //function(arg1,arg2) => function(arg1)(arg2); //function(arg1,arg2,...,argn) => function(arg1)(arg2)(...)(argn) //反柯里化 //obj.func(arg1,arg2) => func(obj,arg1,arg2)
ES6實(shí)現(xiàn)一個(gè)反柯里化
function unCurrying(fn){
//tar 是我們借給的對(duì)象 以前需要xxx.fn(xx) 現(xiàn)在就可以fn(xxx,xx)
return function(tar,...argu){
return fn.apply(tar,argu);
}
}
//比如我們想把Array.prototype.push方法從原生借出來(lái)
let push = unCurrying(Array.prototype.push);
//arrguments是我們借給的對(duì)象
push(arguments,4);
函數(shù)柯里化的高階實(shí)現(xiàn) ,上面的函數(shù)只實(shí)現(xiàn)一層簡(jiǎn)單的柯里化 如果實(shí)現(xiàn)完全的柯里化func(xx)(xx)(xx)(xx)的話(huà),我們要反復(fù)嵌套我們的柯里化函數(shù),這里我們實(shí)現(xiàn)一個(gè)更高階的柯里化通用方法。
function curryingHelper(fn,len){
//這里先說(shuō)個(gè)基本知識(shí)點(diǎn) fn.length 返回的是這個(gè)方法需要傳入的參數(shù)個(gè)數(shù)
//這里第一次運(yùn)行時(shí)通過(guò)fn.length 后面遞歸都是用的傳入的len len為剩余的參數(shù)個(gè)數(shù)
const length = len || fn.length;
return function(...rest){
//判斷這次傳入的參數(shù)是否大于等于剩下的參數(shù) 如果不是遞歸返回下一個(gè)方法繼續(xù)傳參
return rest.length >= length
? fn.apply(this,rest)
: curryingHelper(currying.apply(this,[fn].concat(rest)),length-rest.length)
}
}
//還是剛才的sayHello 函數(shù)
let betterShowMsg = curryingHelper(sayHello);
//自動(dòng)控制傳參層數(shù)
betterShowMsg('zyx')(22)('葡萄');
betterShowMsg('zyx',22)('葡萄');
柯里化的三種用法
1 參數(shù)的復(fù)用
function Say(name,some){
console.log(name + '說(shuō)' + some);
}
//如果我們只想讓zyx說(shuō)一些東西
let zyxSay = currying(Say,'zyx');
zyxSay('1111');//zyx說(shuō)1111
2 提高適用性
//通用函數(shù)解決了兼容性的問(wèn)題,但是同時(shí)在不同場(chǎng)景下,我們可能同一種規(guī)則需要反復(fù)使用
//這就可能會(huì)造成代碼的重復(fù)性 比如
function square(i){ return i*i }//平方
function dubble(i){ return i*2 }//雙倍
function map(handler,list){
//handle 是操作的規(guī)則 list是操作的arrguments
return list.map(handler)
}
map(square,[1,2,3]);//數(shù)組每一項(xiàng)平方
map(dubble,[1,2,3]);//數(shù)組每一項(xiàng)加倍
//這就是通用性 我可以用同一個(gè)函數(shù)做很多不同的操作
//但是如果我們需要大量做平方操作 每次我們都需要傳入方法再傳入數(shù)組就造成的代碼浪費(fèi)
//這時(shí)我們通過(guò)柯里化提高實(shí)用性
let mapSQ = currying(map,square);//直接定義出來(lái)的新的平凡操作函數(shù)
mapSQ([1,2,3]);//以后就不用傳入操作方法了
3 延遲執(zhí)行
let add = function(...rest){
//定義一個(gè)閉包保存_args
const _args = [];
return function cb(...rest){
if(rest.length == 0){
//如果不穿參數(shù)了 也就是add() 說(shuō)明我們需要最后執(zhí)行函數(shù)了
let res = 0;
//累加
console.log(_args);
for(let data of _args){
res += data;
}
return res;
}else{
_args.push(...rest);
//為了鎖住args 閉包
return _args;
}
}
}()
add(1);
add(2);
let a = add();
console.log(a);//3
以上就是淺析JavaScript 函數(shù)柯里化的詳細(xì)內(nèi)容,更多關(guān)于JavaScript 函數(shù)柯里化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript容錯(cuò)處理代碼(屏蔽js錯(cuò)誤)
本文主要介紹了javascript的容錯(cuò)處理代碼。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01
three.js簡(jiǎn)單實(shí)現(xiàn)類(lèi)似七圣召喚的擲骰子
這篇文章主要為大家介紹了three.js簡(jiǎn)單實(shí)現(xiàn)類(lèi)似七圣召喚的擲骰子示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
js控制的回到頁(yè)面頂端goTop的代碼實(shí)現(xiàn)
在瀏覽網(wǎng)頁(yè)的時(shí)候應(yīng)該會(huì)經(jīng)常見(jiàn)到右下角有個(gè)【回到頂端】的懸浮東東,本文也要使用js實(shí)現(xiàn)一下,感興趣的朋友可以參考下哈,希望可以幫助到你2013-03-03
使用偽命名空間封裝保護(hù)獨(dú)自創(chuàng)建的對(duì)象方法
下面小編就為大家?guī)?lái)一篇使用偽命名空間封裝保護(hù)獨(dú)自創(chuàng)建的對(duì)象方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
原生js和jQuery隨意改變div屬性style的名稱(chēng)和值
用原生js和jQuery實(shí)現(xiàn)改變隨意改變div屬性style的名稱(chēng)和值的結(jié)果,這個(gè)實(shí)例比較實(shí)用,新手朋友們可以看看2014-10-10
TypeScript聲明文件的語(yǔ)法與場(chǎng)景詳解
使用ts進(jìn)行開(kāi)發(fā)的時(shí)候,不可避免的需要引用第三方的 JS 的庫(kù),但是默認(rèn)情況下TS是不認(rèn)識(shí)我們引入的這些JS庫(kù)的,所以在使用這些JS庫(kù)的時(shí)候,我們就要通過(guò)聲明文件告訴TS它是什么,這篇文章主要給大家介紹了關(guān)于TypeScript聲明文件的相關(guān)資料,需要的朋友可以參考下2022-05-05

