前端 js 柯里化和反柯里化

函數(shù)柯里化currying的概念最早由俄國(guó)數(shù)學(xué)家Moses Sch?nfinkel發(fā)明前酿,而后由著名的數(shù)理邏輯學(xué)家Haskell Curry將其豐富和發(fā)展滞造,currying由此得名。本文將詳細(xì)介紹函數(shù)柯里化(curring)

定義:

柯里化茄蚯,可以理解為提前接收部分參數(shù)算吩,延遲執(zhí)行哥桥,不立即輸出結(jié)果,而是返回一個(gè)接受剩余參數(shù)的函數(shù)狸捅。因?yàn)檫@樣的特性衷蜓,也被稱(chēng)為部分計(jì)算函數(shù)〕竞龋柯里化磁浇,是一個(gè)逐步接收參數(shù)的過(guò)程。在接下來(lái)的剖析中瞧省,你會(huì)深刻體會(huì)到這一點(diǎn)扯夭。

反柯里化,是一個(gè)泛型化的過(guò)程鞍匾。它使得被反柯里化的函數(shù),可以接收更多參數(shù)骑科。目的是創(chuàng)建一個(gè)更普適性的函數(shù)橡淑,可以被不同的對(duì)象使用

一咆爽、柯里化

剛開(kāi)始接觸到柯里化概念是判斷一個(gè)變量類(lèi)型的時(shí)候

function checkType(type) {
    return function(content) {
        return Object.prototype.toString.call(content) === `[object ${type}]`;
    }
}

let isString = checkType("String");

console.log(isString("sad")); // true

封裝一個(gè)檢測(cè)變量類(lèi)型的函數(shù) checkType梁棠,當(dāng)我們調(diào)用 checkType 的時(shí)候在返回一個(gè)函數(shù),這個(gè)函數(shù)可以拿到 type 參數(shù)斗埂,空間不會(huì)被釋放符糊,柯里化的函數(shù),通用性會(huì)降低呛凶,函數(shù)的功能會(huì)更具體

通用的柯里化函數(shù):
// 通用柯里化函數(shù)
function curring(fn,arr =[]){
    let len = fn.length; // 代表fn需要傳入?yún)?shù)的個(gè)數(shù)
    return function(...args){
        arr = [...arr, ...args];
        if(arr.length < len ){
            // 傳入的參數(shù)達(dá)不到執(zhí)行條件,遞歸繼續(xù)接受參數(shù)
            return curring(fn,arr);
        }else{
            // console.log('111');
            return fn(...arr);
        }
    }
}

下面我們用通用的柯里化函數(shù)男娄,封裝一個(gè)判斷一個(gè)變量類(lèi)型的函數(shù)

// 驗(yàn)證函數(shù)
function checkType(type,value){
    return Object.prototype.toString.call(value) === `[object ${type}]`;
}

// 通用柯里化函數(shù)
function curring(fn,arr =[]){
    // console.log(arr);
    let len = fn.length; // 代表fn需要傳入?yún)?shù)的個(gè)數(shù)
    return function(...args){
        arr = [...arr, ...args];
        // console.log(arr);
        if(arr.length < len ){
            // 傳入的參數(shù)達(dá)不到執(zhí)行條件,遞歸繼續(xù)接受參數(shù)
            return curring(fn,arr);
        }else{
            // console.log('111');
            return fn(...arr);
        }
    }
}

// 生成驗(yàn)證函數(shù)
let util = {};
let types = ['String', 'Number', 'Boolean', 'Null', 'Undefined'];
types.forEach(type => {
    util[`is${type}`] = curring(checkType)(type);
})
console.log(util.isString('hello'))

二、反柯里化

  • 非我之物漾稀,為我所用
  • 增加被反柯里化方法接收的參數(shù)
// 輕提示
function Toast(option){
    this.prompt = '';
  }
  Toast.prototype = {
    constructor: Toast,
    // 輸出提示
    show: function(){
      console.log(this.prompt);
    }
  };
  
  // 新對(duì)象
  var obj = {
      prompt: '新對(duì)象'
  };
  
  function unCurrying(fn){
      return function(){
          var args = [].slice.call(arguments);
          console.log(args);
          var that = args.shift();
          return fn.apply(that);
      }
  }
  
  var objShow = unCurrying(Toast.prototype.show);
  
  objShow(obj); // 輸出"新對(duì)象"

在上面的例子中模闲,Toast.prototype.show 方法,本來(lái)是 Toast 類(lèi)的私有方法崭捍。跟新對(duì)象 obj 沒(méi)有半毛錢(qián)關(guān)系尸折。
經(jīng)過(guò)反柯里化后,卻可以為 obj 對(duì)象所用殷蛇。
為什么能被 obj 所用实夹,是因?yàn)閮?nèi)部將 Toast.prototype.show 的上下文重新定義為 obj。也就是用 apply 改變了this指向粒梦。
而實(shí)現(xiàn)這一步驟的過(guò)程亮航,就需要增加反柯里化后的 objShow 方法參數(shù)。

參考文檔:

https://www.imooc.com/article/46624

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谍倦,一起剝皮案震驚了整個(gè)濱河市塞赂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昼蛀,老刑警劉巖宴猾,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圆存,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仇哆,警方通過(guò)查閱死者的電腦和手機(jī)沦辙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讹剔,“玉大人油讯,你說(shuō)我怎么就攤上這事⊙忧罚” “怎么了陌兑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)由捎。 經(jīng)常有香客問(wèn)我兔综,道長(zhǎng),這世上最難降的妖魔是什么狞玛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任软驰,我火速辦了婚禮,結(jié)果婚禮上心肪,老公的妹妹穿的比我還像新娘锭亏。我一直安慰自己,他們只是感情好硬鞍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布慧瘤。 她就那樣靜靜地躺著,像睡著了一般膳凝。 火紅的嫁衣襯著肌膚如雪碑隆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天蹬音,我揣著相機(jī)與錄音上煤,去河邊找鬼。 笑死著淆,一個(gè)胖子當(dāng)著我的面吹牛劫狠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播永部,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼独泞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了苔埋?” 一聲冷哼從身側(cè)響起懦砂,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荞膘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體罚随,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年羽资,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淘菩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屠升,死狀恐怖潮改,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腹暖,我是刑警寧澤汇在,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脏答,受9級(jí)特大地震影響趾疚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜以蕴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辛孵。 院中可真熱鬧丛肮,春花似錦、人聲如沸魄缚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)冶匹。三九已至习劫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嚼隘,已是汗流浹背诽里。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留飞蛹,地道東北人谤狡。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像卧檐,于是被迫代替她去往敵國(guó)和親墓懂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355