<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文帶你搞懂JavaScript Currying(柯里化)函數(shù)

          共 2632字,需瀏覽 6分鐘

           ·

          2021-09-29 14:34

          點(diǎn)擊上方“前端進(jìn)階學(xué)習(xí)交流”,進(jìn)行關(guān)注

          回復(fù)“前端”即可獲贈(zèng)前端相關(guān)學(xué)習(xí)資料

          落紅不是無情物,化作春泥更護(hù)花。

          大家好,我是進(jìn)階學(xué)習(xí)者。

          一、什么柯里化(Currying)?

          柯里化(Currying)是一種關(guān)于函數(shù)的高階技術(shù)。它不僅被用于 JavaScript,還被用于其他編程語言。

          柯里化是一種函數(shù)的轉(zhuǎn)換,它是指將一個(gè)函數(shù)從可調(diào)用的 f(a, b, c) 轉(zhuǎn)換為可調(diào)用的 f(a)(b)(c)??吕锘粫?huì)調(diào)用函數(shù)。它只是對(duì)函數(shù)進(jìn)行轉(zhuǎn)換。


          二、案例

          例:

          將創(chuàng)建一個(gè)輔助函數(shù) curry(f),該函數(shù)將對(duì)兩個(gè)參數(shù)的函數(shù) f 執(zhí)行柯里化。換句話說,對(duì)于兩個(gè)參數(shù)的函數(shù) f(a, b) 執(zhí)行 curry(f) 會(huì)將其轉(zhuǎn)換為以 f(a)(b) 形式運(yùn)行的函數(shù):

          function curry(f) {  // curry(f) 執(zhí)行柯里化轉(zhuǎn)換  return function(a) {    return function(b) {      return f(a, b);    };  };}// 用法function sum(a, b) {  return a + b;}let curriedSum = curry(sum);alert( curriedSum(1)(2) ); // 3

          運(yùn)行結(jié)果:

          注:

          正如所看到的,實(shí)現(xiàn)非常簡(jiǎn)單:只有兩個(gè)包裝器(wrapper)。

          1. curry(func) 的結(jié)果就是一個(gè)包裝器 function(a)。

          2. 當(dāng)它被像 curriedSum(1) 這樣調(diào)用時(shí),它的參數(shù)會(huì)被保存在詞法環(huán)境中,然后返回一個(gè)新的包裝器 function(b)。

          3. 然后這個(gè)包裝器被以 2 為參數(shù)調(diào)用,并且,它將該調(diào)用傳遞給原始的 sum 函數(shù)。

          三、目的是什么?它有什么好處?

          例:

          要了解,需要一個(gè)實(shí)際中的例子。

          有一個(gè)用于格式化和輸出信息的日志(logging)函數(shù) log(date, importance, message)。在實(shí)際項(xiàng)目中,此類函數(shù)具有很多有用的功能,例如通過網(wǎng)絡(luò)發(fā)送日志(log),在這兒僅使用 alert:

          function log(date, importance, message) {  alert([${date.getHours()}:${date.getMinutes()}] [${importance}] ${message});}

          讓將它柯里化!

          log = _.curry(log);

          柯里化之后,log 仍正常運(yùn)行:

          log(new Date(), "DEBUG", "some debug"); // log(a, b, c)

          運(yùn)行結(jié)果:

          ……但是也可以以柯里化形式運(yùn)行:

          log(new Date())("DEBUG")("some debug"); // log(a)(b)(c)

          運(yùn)行結(jié)果:

          現(xiàn)在,可以輕松地為當(dāng)前日志創(chuàng)建便捷函數(shù):

          // logNow 會(huì)是帶有固定第一個(gè)參數(shù)的日志的偏函數(shù)let logNow = log(new Date());// 使用它
          logNow("INFO", "message"); // [HH:mm] INFO message

          現(xiàn)在,logNow 是具有固定第一個(gè)參數(shù)的 log,換句話說,就是更簡(jiǎn)短的“偏應(yīng)用函數(shù)(partially applied function)”或“偏函數(shù)(partial)”。

          可以更進(jìn)一步,為當(dāng)前的調(diào)試日志(debug log)提供便捷函數(shù):

          let debugNow = logNow("DEBUG");debugNow("message"); // [HH:mm] DEBUG message

          注:

          1. 柯里化之后,沒有丟失任何東西:log 依然可以被正常調(diào)用。

          2. 可以輕松地生成偏函數(shù),例如用于生成今天的日志的偏函數(shù)。

          四、高級(jí)柯里化實(shí)現(xiàn)

          下面是用于多參數(shù)函數(shù)的“高級(jí)”柯里化實(shí)現(xiàn),也可以把它用于上面的示例。

          function curry(func) {   return function curried(...args) {        if (args.length >= func.length) {            return func.apply(this, args);    }     else {      return function(...args2) {       return curried.apply(this, args.concat(args2));          }            }   };}

          例:

          function sum(a, b, c) {    return a + b + c;}let curriedSum = curry(sum);alert( curriedSum(1, 2, 3) ); // 6,仍然可以被正常調(diào)用alert( curriedSum(1)(2,3) ); // 6,對(duì)第一個(gè)參數(shù)的柯里化alert( curriedSum(1)(2)(3) ); // 6,全柯里化

          運(yùn)行結(jié)果:


          五、總結(jié)

          本文基于JavaScript基礎(chǔ),介紹了Currying  函數(shù)。Currying 是一種轉(zhuǎn)換,將 f(a,b,c) 轉(zhuǎn)換為可以被以 f(a)(b)(c) 的形式進(jìn)行調(diào)用。

          JavaScript 實(shí)現(xiàn)通常都保持該函數(shù)可以被正常調(diào)用,并且如果參數(shù)數(shù)量不足,則返回偏函數(shù)。Currying  函數(shù)讓能夠更容易地獲取偏函數(shù)。通過按案例的分析進(jìn)行詳細(xì)的講解。

          代碼很簡(jiǎn)單,希望對(duì)你學(xué)習(xí)有幫助。

          ------------------- End -------------------

          往期精彩文章推薦:

          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入前端學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群

          萬水千山總是情,點(diǎn)個(gè)【在看】行不行

          瀏覽 31
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青娱乐在线视频国产 | 自慰大秀 | 天天看搞欧美 | 天天澡日日久综合 | 97久久爽无码人妻AⅤ精品牛牛 |