JS柯里化

前言

柯里化(Currying),又稱部分求值(Partial Evaluation),是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)

正文

簡(jiǎn)單柯里化

假設(shè)有一個(gè)數(shù)組,要對(duì)其中每一個(gè)元素進(jìn)行同樣操作,比如加一或加二

const arr1 = [0, 1, 2, 3];
let   arr2 = arr1.map(e => e+1); //加一
let   arr3 = arr1.map(e => e+2); //加二

那么是根據(jù)情況加不同的值,又不依賴全局變量,怎么處理,于是想把map里的1,2變成參數(shù),但是通過(guò)map無(wú)法傳遞該參數(shù),以下一個(gè)普通簡(jiǎn)單寫法

let func = function (arr,add) {
    arr = arr.map(e => e + add)
    return arr;
}
const arr1 = [0, 1, 2, 3];
let arr2 = func(arr1,3);

柯里化就是下面

let func = function (arr) {
    return function (add) {
        let arr_add = arr.map(e => e + add)
        return arr_add;
    }
}
const arr1 = [0, 1, 2, 3];
let arr2 = func(arr1)(3);

這是一種簡(jiǎn)單的柯里化,上面的func方法相當(dāng)于是一個(gè)函數(shù)工廠,返回的是一個(gè)函數(shù),也可以直接func2 = func(arr1),后面在靈活的根據(jù)某個(gè)值n執(zhí)行func2(n)來(lái)返回想要的數(shù)組

柯里化思想

柯里化部分求值,也就是延遲求值,等到需要的時(shí)候再求值
比如說(shuō)要做累加,使用一個(gè)很簡(jiǎn)單的全局變量就可以實(shí)現(xiàn),有一個(gè)專門的方法把傳參加到全局變量上,但這樣做當(dāng)數(shù)據(jù)量很大時(shí)會(huì)很耗費(fèi)資源,所以可以使用一個(gè)方法吧這些臨時(shí)值先全部收集起來(lái),等到我們想要實(shí)現(xiàn)運(yùn)算的時(shí)候再取執(zhí)行運(yùn)算
比如說(shuō)這樣:

let collect = (() => {
    let arr = [];                     //做一個(gè)閉包來(lái)存儲(chǔ)值
    return function () {
        if (arguments.length === 0) { //開(kāi)始計(jì)算
            let count = 0;
            arr.forEach((v, k)=>{
                count += v;
            });
            return count;
            arr = null;              //無(wú)用釋放
        } else {
            Array.prototype.push.apply(arr,arguments);
        }
    }
})();
collect(1);
collect(1);
collect(1.5);
console.log(collect());             //3.5

這不是一個(gè)真正柯里化,這段代碼是為了幫助理解柯里化延遲計(jì)算的思想

柯里化實(shí)現(xiàn)

目標(biāo):把類似collect(1,2,3,4)的方法按collect(1)(2)(3)(4)方式執(zhí)行,其實(shí)很像建造者模式, 在js里就相應(yīng)的使用閉包來(lái)模擬私有變量存儲(chǔ)這些參數(shù)
以下一段網(wǎng)上柯里化通用的方法

var curry = function (fn) {
    var _args = [];                  //存儲(chǔ)參數(shù)待執(zhí)行
    return function () {
        if (arguments.length === 0) {
            return fn.apply(this, _args);
        }
        Array.prototype.push.apply(_args, Array.prototype.slice.call(arguments));
        return arguments.callee;    //返回匿名函數(shù)
    }
};
var collect = function () {
    var total = 0;
    for (var i = 0, c; c = arguments[i++];) {
        total += c;
    }
    console.log(total);
}
var bulider =  curry(collect);     //來(lái)個(gè)類似builder的寫法
bulider = bulider(1);
bulider = bulider(1,2);
bulider = bulider(3);
bulider();    //7
var collect2 = curry(collect);
collect2(1)(2)(3)(); //6

柯里化的好處

  1. 參數(shù)復(fù)用;
  2. 提前返回;
  3. 延遲計(jì)算/運(yùn)行;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 標(biāo)簽: js柯里化 js柯里化 柯里化是什么在計(jì)算機(jī)科學(xué)中,柯里化(Currying)是把接受多個(gè)參數(shù)的函數(shù)變換成...
    廣州蘆葦科技web前端閱讀 718評(píng)論 0 0
  • 函數(shù)柯里化currying的概念最早由俄國(guó)數(shù)學(xué)家Moses Sch?nfinkel發(fā)明,而后由著名的數(shù)理邏輯學(xué)家H...
    alokka閱讀 216評(píng)論 0 0
  • 前言 我們?cè)诟鞣N算法題以及技術(shù)文檔中經(jīng)常會(huì)看到柯里化這個(gè)詞,那么,柯里化到底是什么?它在js中如何運(yùn)用?對(duì)我們的編...
    南宮__閱讀 3,979評(píng)論 0 24
  • 原文: Eric Elliott - Curry and Function Composition 譯文: cur...
    xiaohesong閱讀 2,078評(píng)論 0 5
  • 柯里化:函數(shù)接受一些參數(shù),但不立即求值;返回一個(gè)匿名函數(shù)將參數(shù)保存下來(lái);需要求值時(shí)將保存的全部參數(shù)一起用掉。(保存...
    吃蘿卜的小兔子閱讀 256評(píng)論 0 0

友情鏈接更多精彩內(nèi)容