亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

關(guān)于javascript函數(shù)式編程中compose的實(shí)現(xiàn)

jonh_felix / 3017人閱讀

摘要:結(jié)論這次主要介紹了函數(shù)式編程中的函數(shù)的原理和實(shí)現(xiàn)方法,由于篇幅原因,我把打算分析的源碼實(shí)現(xiàn)放到下一篇來介紹,可以說實(shí)現(xiàn)的更加函數(shù)式,需要多帶帶好好分析。

上一篇文章介紹了javascript函數(shù)式編程中curry(柯里化)的實(shí)現(xiàn),當(dāng)然那個(gè)柯里化是有限參數(shù)的柯里化,等有機(jī)會(huì)在補(bǔ)上無限參數(shù)的那一種柯里化,這次主要說的是javascript函數(shù)式編程中另外一個(gè)很重要的函數(shù)compose,compose函數(shù)的作用就是組合函數(shù)的,將函數(shù)串聯(lián)起來執(zhí)行,將多個(gè)函數(shù)組合起來,一個(gè)函數(shù)的輸出結(jié)果是另一個(gè)函數(shù)的輸入?yún)?shù),一旦第一個(gè)函數(shù)開始執(zhí)行,就會(huì)像多米諾骨牌一樣推導(dǎo)執(zhí)行了。

簡(jiǎn)介

比如有這樣的需求,要輸入一個(gè)名字,這個(gè)名字有由firstName,lastName組合而成,然后把這個(gè)名字全部變成大寫輸出來,比如輸入jacksmith我們就要打印出來,‘HELLO,JACK SMITH’ 。
我們考慮用函數(shù)組合的方法來解決這個(gè)問題,需要兩個(gè)函數(shù)greeting, toUpper

var greeting = (firstName, lastName) => "hello, " + firstName + " " + lastName
var toUpper = str => str.toUpperCase()
var fn = compose(toUpper, greeting)
console.log(fn("jack", "smith"))
// ‘HELLO,JACK SMITH’

這就是compose大致的使用,總結(jié)下來要注意的有以下幾點(diǎn)

compose的參數(shù)是函數(shù),返回的也是一個(gè)函數(shù)

因?yàn)槌说谝粋€(gè)函數(shù)的接受參數(shù),其他函數(shù)的接受參數(shù)都是上一個(gè)函數(shù)的返回值,所以初始函數(shù)的參數(shù)是多元的,而其他函數(shù)的接受值是一元

compsoe函數(shù)可以接受任意的參數(shù),所有的參數(shù)都是函數(shù),且執(zhí)行方向是自右向左的,初始函數(shù)一定放到參數(shù)的最右面

知道這三點(diǎn)后,就很容易的分析出上個(gè)例子的執(zhí)行過程了,執(zhí)行fn("jack", "smith")的時(shí)候,初始函數(shù)為greeting,執(zhí)行結(jié)果作為參數(shù)傳遞給toUpper,再執(zhí)行toUpper,得出最后的結(jié)果,compose的好處我簡(jiǎn)單提一下,如果還想再加一個(gè)處理函數(shù),不需要修改fn,只需要在執(zhí)行一個(gè)compose,比如我們?cè)傧爰右粋€(gè)trim,只需要這樣做

var trim = str => str.trim()
var newFn = compose(trim, fn)
console.log(newFn("jack", "smith"))

就可以了,可以看出不論維護(hù)和擴(kuò)展都十分的方便。

實(shí)現(xiàn)

例子分析完了,本著究其根本的原則,還是要探究與一下compose到底是如何實(shí)現(xiàn)的,首先解釋介紹一下我是如何實(shí)現(xiàn)的,然后再探求一下,javascript函數(shù)式編程的兩大類庫(kù),lodash.jsramda.js是如何實(shí)現(xiàn)的,其中ramda.js實(shí)現(xiàn)的過程非常函數(shù)式。

我的實(shí)現(xiàn)

我的思路是,既然函數(shù)像多米諾骨牌式的執(zhí)行,我首先就想到了遞歸,下面就一步一步的實(shí)現(xiàn)這個(gè)compose,首先,compose返回一個(gè)函數(shù),為了記錄遞歸的執(zhí)行情況,還要記錄參數(shù)的長(zhǎng)度len,還要給返回的函數(shù)添加一個(gè)名字f1。

var compose = function(...args) {
    var len = args.length
    return function f1() {
        
    }
}

函數(shù)體里面要做的事情就是不斷的執(zhí)行args中的函數(shù),將上一個(gè)函數(shù)的執(zhí)行結(jié)果作為下一個(gè)執(zhí)行函數(shù)的輸入?yún)?shù),需要一個(gè)游標(biāo)count來記錄args函數(shù)列表的執(zhí)行情況。

var compose = function(...args) {
    var len = args.length
    var count = len - 1
    var result
    return function f1(...args1) {
        result = args[count].apply(this, args1)
        count--
        return f1.call(null, result)
    }
}

這個(gè)就是思路,當(dāng)然這樣是不行的,沒有退出條件,遞歸的退出條件就是最后一個(gè)函數(shù)執(zhí)行完的時(shí)候,也就是count0的時(shí)候,這時(shí)候,有一點(diǎn)要注意,遞歸退出的時(shí)候,count游標(biāo)一定要回歸初始狀態(tài),最后補(bǔ)充一下代碼

var compose = function(...args) {
        var len = args.length
        var count = len - 1
        var result
        return function f1(...args1) {
            result = args[count].apply(this, args1)
            if (count <= 0) {
                count = len - 1
                return result
            } else {
                count--
                return f1.call(null, result)
            }
        }
    }

這樣就實(shí)現(xiàn)了這個(gè)compose函數(shù)。后來我發(fā)現(xiàn)遞歸這個(gè)完全可以使用迭代來實(shí)現(xiàn),使用while函數(shù)看起來更容易明白,其實(shí)lodash.js就是這么實(shí)現(xiàn)的。

lodash實(shí)現(xiàn)

lodash的思路同上,不過是用迭代實(shí)現(xiàn)的,我就把它的源代碼貼過來看一下

var flow = function(funcs) {
    var length = funcs.length
    var index = length
    while (index--) {
        if (typeof funcs[index] !== "function") {
            throw new TypeError("Expected a function");
        }
    }
    return function(...args) {
        var index = 0
        var result = length ? funcs[index].apply(this, args) : args[0]
        while (++index < length) {
            result = funcs[index].call(this, result)
        }
        return result
    }
}
var flowRight = function(funcs) {
    return flow(funcs.reverse())
}

可以看出,lodash的本來實(shí)現(xiàn)是從左到右的,但也提供了從右到左flowRight,還多了一層函數(shù)的校驗(yàn),而且接收的是數(shù)組,不是參數(shù)序列,而且從這行var result = length ? funcs[index].apply(this, args) : args[0]可以看出允許數(shù)組為空,可以看出還是非常嚴(yán)謹(jǐn)?shù)?。我寫的就缺少這種嚴(yán)謹(jǐn)?shù)漠惓L幚怼?/p> 結(jié)論

這次主要介紹了函數(shù)式編程中的compose函數(shù)的原理和實(shí)現(xiàn)方法,由于篇幅原因,我把打算分析的ramda.js源碼實(shí)現(xiàn)放到下一篇來介紹,可以說ramda.js實(shí)現(xiàn)的compose更加函數(shù)式,需要多帶帶好好分析。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/81571.html

相關(guān)文章

  • 翻譯連載 | JavaScript輕量級(jí)函數(shù)編程-第4章:組合函數(shù) |《你不知道JS》姊妹篇

    摘要:把數(shù)據(jù)的流向想象成糖果工廠的一條傳送帶,每一次操作其實(shí)都是冷卻切割包裝糖果中的一步。在該章節(jié)中,我們將會(huì)用糖果工廠的類比來解釋什么是組合。糖果工廠靠這套流程運(yùn)營(yíng)的很成功,但是和所有的商業(yè)公司一樣,管理者們需要不停的尋找增長(zhǎng)點(diǎn)。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個(gè)流淌...

    JowayYoung 評(píng)論0 收藏0
  • JavaScript 函數(shù)編程(二)

    摘要:注意是單一參數(shù)柯里化是由以邏輯學(xué)家命名的,當(dāng)然編程語言也是源自他的名字,雖然柯里化是由和發(fā)明的。辨別類型和它們的含義是一項(xiàng)重要的技能,這項(xiàng)技能可以讓你在函數(shù)式編程的路上走得更遠(yuǎn)。 slide 地址 三、可以,這很函數(shù)式~ showImg(https://segmentfault.com/img/remote/1460000015978685?w=187&h=160); 3.1.函數(shù)是一...

    thursday 評(píng)論0 收藏0
  • 函數(shù)編程興衰與當(dāng)前之崛起

    摘要:函數(shù)式編程逐漸被邊緣化,被拋棄到學(xué)術(shù)界和非主流的場(chǎng)外。組合式編程的重新崛起年左右,有個(gè)巨大的變化爆發(fā)了。人們開始逐漸在私下里談?wù)摵瘮?shù)式編程。箭頭函數(shù)對(duì)于函數(shù)式編程的爆發(fā)起到了推動(dòng)劑的作用?,F(xiàn)在很少看到那種不用函數(shù)式編程的大型應(yīng)用了。 showImg(https://segmentfault.com/img/remote/1460000009036867?w=800&h=364); 本...

    binaryTree 評(píng)論0 收藏0
  • Js-函數(shù)編程

    摘要:組合組合的功能非常強(qiáng)大,也是函數(shù)式編程的一個(gè)核心概念,所謂的對(duì)過程進(jìn)行封裝很大程度上就是依賴于組合。在理解之前,先認(rèn)識(shí)一個(gè)東西概念容器容器為函數(shù)式編程里普通的變量對(duì)象函數(shù)提供了一層極其強(qiáng)大的外衣,賦予了它們一些很驚艷的特性。 前言 JavaScript是一門多范式語言,即可使用OOP(面向?qū)ο螅?,也可以使用FP(函數(shù)式),由于筆者最近在學(xué)習(xí)React相關(guān)的技術(shù)棧,想進(jìn)一步深入了解其思想...

    whinc 評(píng)論0 收藏0
  • 使用 javascript 小技巧

    摘要:與條件判斷一般我們判斷或用如果我們有更多水果與去重提供了新的數(shù)據(jù)結(jié)構(gòu)。所以所有的關(guān)于數(shù)據(jù)的操作,都可以用函數(shù)式的方式處理。這樣做的可讀性遠(yuǎn)遠(yuǎn)高于嵌套一大堆的函數(shù)調(diào)用我們選擇一些函數(shù),讓它們結(jié)合,生成一個(gè)嶄新的函數(shù)。 1、Array.includes 與條件判斷 一般我們判斷或用 || // condition function test(fruit) { if (fruit...

    econi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<