最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中函數(shù)科里化的背景與應(yīng)用實例教程

 更新時間:2022年06月06日 09:16:11   作者:程序媛徐嬋  
在數(shù)學(xué)和計算機科學(xué)中,柯里化是一種將使用多個參數(shù)的一個函數(shù)轉(zhuǎn)換成一系列使用一個參數(shù)的函數(shù)的技術(shù),下面這篇文章主要給大家介紹了JS中函數(shù)科里化的背景與應(yīng)用實例的相關(guān)資料,需要的朋友可以參考下

背景

柯里化(Currying)是一種關(guān)于函數(shù)的高階技術(shù)。它不僅被用于 JavaScript,還被用于其他編程語言。函數(shù)柯里化又叫部分求值,維基百科中對柯里化 (Currying) 的定義為:

在數(shù)學(xué)和計算機科學(xué)中,柯里化是一種將使用多個參數(shù)的函數(shù)轉(zhuǎn)換成一系列使用一個參數(shù)的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。

用大白話來說就是只傳遞給函數(shù)一部分參數(shù)來調(diào)用它,讓它返回一個新函數(shù)去處理剩下的參數(shù)。使用一個簡單的例子來介紹下,最常用的就是 add 函數(shù)了。

// add method
const add = (...args) => args.reduce((a, b) => a + b);

// 傳入多個參數(shù),執(zhí)行 add 函數(shù)
add(1, 2) // 返回 3

// 假設(shè)我們實現(xiàn)了一個 currying 函數(shù),支持一次傳入一個參數(shù)
let sum = currying(add);
let addCurryOne = sum(1);
addCurryOne(2) // 返回 3
addCurryOne(3) // 返回 4

使用場景

柯里化是一種函數(shù)的轉(zhuǎn)換,它是指將一個函數(shù)從可調(diào)用的 f(a, b, c) 轉(zhuǎn)換為可調(diào)用的 f(a)(b)(c)??吕锘粫{(diào)用函數(shù)。它只是對函數(shù)進行轉(zhuǎn)換。 在平常工作中主要使用場景如下:

  • 1、延遲計算(部分求和、bind 函數(shù))

  • 2、動態(tài)創(chuàng)建函數(shù)(添加監(jiān)聽 addEvent、惰性函數(shù))

  • 3、參數(shù)復(fù)用(Function.prototype.call.bind(Object.prototype.toString))

JS中的函數(shù)科里化

可以對比下haskell這種天然的函數(shù)式語言,js里的珂里化實在是殘缺不全...但是利用珂里化這種參數(shù)對應(yīng)函數(shù)的思想,結(jié)合js的閉包特性,來實現(xiàn)良好的封裝。 舉個例子:js中最常見的dom的插入和刪除。 普通寫法:變量都在外部,不能確保每個remove操作都“正確”的

var append = function (parent, child) {
    parent.appendChild(child);
}
var remove = function (dom) {
    dom.remove();
}
//插入 remove(child); //刪除
append(parent, child); 

文藝寫法:確保了每個刪除操作都會刪除插入的節(jié)點。

var append = function (parent, child) {
    parent.appendChild(child);
    return function () {
        child.remove();
    }
}

//或者是這種,point free風格 
var append2 = function (parent, child) {
    parent.appendChild(child);
    return child.remove.bind(child);
}
//插入一個節(jié)點,同時返回所插入的節(jié)點的刪除操作。 remove(); //刪除。
var remove = append(parent, child);

總結(jié)一下就是說,這種以函作為主體,確保了函數(shù)之間不會相互干擾,尤其是在復(fù)雜的前端工程下,每一處的代碼越“安全”,越獨立,越能更好的拓展功能和排查問題。

經(jīng)典面試題:add(1)(2)(3)

function add(seed) {
    function retVal(later) {
        return add(seed + later);
    }
    retVal.toString = function () {
        return seed;
    };
    return retVal;
}
console.log(add(1)(2)(3).toString()); // 6

add函數(shù)返回閉包retVal,在retVal中又繼續(xù)調(diào)用add,最終我們可以寫成add(1)(2)(3)(...)這樣柯里化的形式。 每調(diào)用一次add函數(shù),都會返回retValue函數(shù);調(diào)用retValue函數(shù)會調(diào)用add函數(shù),然后還是返回retValue函數(shù),所以調(diào)用add的結(jié)果一定是返回一個retValue函數(shù)。add函數(shù)的存在意義只是為了提供閉包,這個類似的遞歸調(diào)用每次調(diào)用add都會生成一個新的閉包。

總結(jié)

優(yōu)點:

  • 參數(shù)復(fù)用
  • 提前返回
  • 延遲計算/運行

缺點:

  • 函數(shù)柯里化可以用來構(gòu)建復(fù)雜的算法 和 功能, 但是濫用也會帶來額外的開銷。從上面實現(xiàn)部分的代碼中,可以看到,使用柯里化函數(shù),離不開閉包, arguments, 遞歸。
  • 閉包,函數(shù)中的變量都保存在內(nèi)存中,內(nèi)存消耗大,有可能導(dǎo)致內(nèi)存泄漏。
  • 遞歸,效率非常
  • arguments, 變量存取慢,訪問性很差

我個人覺得柯里化并非是必須的,而且不熟悉的同學(xué)閱讀起來可能會遇到麻煩,但是它能幫助我們理解JS中的函數(shù)式編程,更重要的是,我們以后在閱讀類似的代碼時,不會感到陌生。

并非“柯里化”對函數(shù)式編程有意義。而是,函數(shù)式編程在把函數(shù)當作一等公民的同時,就不可避免的會產(chǎn)生“柯里化”這種用法。所以它并不是因為“有什么意義”才出現(xiàn)的。

到此這篇關(guān)于JS中函數(shù)科里化的背景與應(yīng)用的文章就介紹到這了,更多相關(guān)JS函數(shù)科里化應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

庆云县| 鄯善县| 文昌市| 理塘县| 汽车| 通榆县| 久治县| 赤水市| 克东县| 湖南省| 塔河县| 芜湖县| 鲁山县| 邵东县| 眉山市| 炉霍县| 湘潭市| 上林县| 玉溪市| 淮滨县| 清河县| 乌拉特中旗| 察隅县| 永平县| 始兴县| 乌苏市| 聊城市| 望都县| 定州市| 波密县| 修武县| 盐亭县| 杂多县| 汤阴县| 西贡区| 威信县| 钟祥市| 博野县| 潮州市| 吉林市| 古交市|