<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] >[success] # 函數組合 ~~~ 1.純函數和柯里化很容易寫出洋蔥代碼 h(g(f(x))),形成層級嵌套的效果,舉個例子: 1.1.獲取數組的最后一個元素再轉換成大寫字母, _.toUpper(_.first(_.reverse(array))) 2.想解決這種層級不停函數嵌套的形式,就可以使用'函數組合': 2.1.函數組合可以讓我們把細粒度的函數重新組合生成一個新的函數 2.2.如果一個函數要經過多個函數處理才能得到最終值,這個時候可以把中間 過程的函數合并成一個函數 2.3.把中間過程形成的函數就像是數據的管道,函數組合就是把這些管道連接起來, 讓數據穿過多個管道形成最終 結果 2.4.函數組合默認是從右到左執行 ~~~ [函數的組合文章推薦](https://www.dazhuanlan.com/2019/12/17/5df7df78c7e15/?__cf_chl_jschl_tk__=5686af4f074081fa844e5a2ded6cc22f6d401792-1602936568-0-ATGze-SfaXtb9rvAD8Oc41ZRwpV1HkARNrmVxVKG_4e3qe0rBro9V5XKaenUd6CZqKS1gzNSuLO8keFSRpLUTpW1NenDSbiUsYj5pdDiQWXxL5tvqFza4KAT77fTG6gC2PRF8hkFaoJNu2iiufnb1jGQZeLLSX3dGQ54v018DYGavHNtomOmUO7hCupaaPQ4PIUzg135IeHEBbgBjq7Xojfce196OQ62O2PtXT7NoxOvGftf5HBJBaRyFv8uTelwgbDKUs5WN3CogSoJbymgK-WX2JLklfn4dr5oGqubmoUz4A25zMjcjIETLTJfQtIgpg) [文章推薦](https://juejin.im/post/6844903910834962446#heading-0) ![](https://img.kancloud.cn/44/94/44945625c02ad62a8188352884105b73_478x435.png) >[info] ## 管道概念 ~~~ 1.現在有一個需求先轉成大寫,在倒敘展示字符串,正常的話代碼就像案例一一樣, 封裝了一個'toUpperAndReverse' 并且將整個邏輯全部都附加進去,換一種思路如果使用的是 函數式,我們將'split' ,'reverse','join' 這些執行步驟封裝成函數式,形成拼圖形式的組合, 但又不想形成洋蔥模型形式的代碼,我們就需要定義一個'管道'來幫忙處理 2.案例二,嘗試使用案例一引申提出的假設,將代碼重構 3.通過案例二這種不停的分割寫法,在定義感覺上反而感覺更加麻煩了,但是好處就是配合函數 式編程讓整個條件的組合情況變得更多 ~~~ [關于鏈式和組合](https://zhuanlan.zhihu.com/p/60768220) >[danger] ##### 結合律 ~~~ 1.結合律死一個數學的概念指在一個包含有二個以上的可結合運算子的表示式, 只要算子的位置沒有改變,其運算的順序就不會對運算出來的值有影響公式表示:'a+(b+c)=(a+b)+c' 2.函數組合還要符合結合律,也就是這個管道函數'compose'傳參要符合結合律的形式舉個列子: compose(f, compose(g, h)) // 等同于 compose(compose(f, g), h) // 等同于 compose(f, g, h) 因此組合函數必須是純函數 ~~~ >[danger] ##### 案例一 ![](https://img.kancloud.cn/e8/74/e874ef2c61ec79f29e6cda3acd34e9c8_695x84.png) ~~~ let str = 'jspool'; // 先轉成大寫,在倒敘數組的形式展示 function toUpperAndReverse(str) { let upperStr = str.toUpperCase(); return upperStr.split('').reverse().join(''); } console.log(toUpperAndReverse(str)) // LOOPSJ ~~~ >[danger] ##### 案例二 ![](https://img.kancloud.cn/7a/07/7a073f618891225bdd2cec6a9cc9bb06_694x152.png) ~~~ 1.案例二不在進行大寫這一步 2.管道的參數遵守'從右到左執行' ~~~ ~~~ const split = (format) => (str) => str.split(format) const reverse = (list) => list.reverse() const join = (format) => (str) => str.join(format) // 組合函數 function compose(f, g, z) { return function (x) { // 先忽略洋蔥形式 return f(g(z(x))) } } const x = join('') const z = split('') // 使用我們的管道 const fn = compose(x, reverse, z) console.log(fn(str)) // loopsj ~~~ >[info] ## Lodash函數組合 ~~~ 1.Lodash 作為函數式的代表也有一個函數組合的方法'flow()' 和 'flowRight()' 1.1.flow() 是從左到右運行 1.2.flowRight() 是從右到左運行,使用的更多一些 ~~~ >[danger] ##### 使用效果 ~~~ const _ = require('lodash') const reverse = arr => arr.reverse() const first = arr => arr[0] const toUpper = s => s.toUpperCase() const f = _.flowRight(toUpper, first, reverse) console.log(f(['one', 'two', 'three'])) ~~~ >[danger] ##### lodash 在組合函數中使用結合律效果 ~~~ const _ = require('lodash') // const f = _.flowRight(_.toUpper, _.first, _.reverse) // const f = _.flowRight(_.flowRight(_.toUpper, _.first), _.reverse) const f = _.flowRight(_.toUpper, _.flowRight(_.first, _.reverse)) console.log(f(['one', 'two', 'three'])) ~~~ >[info] ## 實現一個自己的管道函數 ~~~ 1.上面我們自己的管道是通過洋蔥的形式,寫死的,這個就要手動實現一個,像lodash一樣 的動態的管道函數 ~~~ >[danger] ##### 代碼的實現 ~~~ 1.注意組合函數,一般默認是'從右往左',下面就有兩種思路實現一種是反轉數組配合'reduce', 另外一種是配合'reduceRight'直接從右往左 2.這里還要對'reduce'做個說明,首先函數式的原因是有輸入和輸出的,因此 acc累加器上一次調用回調函數 拿到的結果實際是之前回調 處理過的返回值,其實就是一個扁平化的洋蔥 ~~~ ~~~ const split = (format) => (str) => str.split(format) const reverse = (list) => list.reverse() const join = (format) => (str) => str.join(format) const x = join('') const z = split('') // 仿寫一個函數組合 的管道 function compose(...fns) { return function (val) { // 從右往往左 先反轉 如果不想反轉直接使用reduceRight return fns.reverse().reduce((acc, fn) => { return fn(acc); }, val) } } var fn = compose(x, reverse, z) console.log(fn(str)) // loopsj // es6 // const compose = (...args) => value => args.reverse().reduce((acc, fn) => fn(acc), value) ~~~ >[info] ## 調試 ~~~ 1.現在將原本捏合在一起的代碼通過 函數式的形式進行了重新切割編程了一個個函數式,整體的調試 如果是在有源碼的情況,可以在每個函數式的代碼中增加console,但如果想'lodash' 這種現成封裝好的 庫需要用另外一種思路 2.首先思考在管道中執行的代碼順序是從右往左一次執行,如果在對應的兩者參數直接加一個打印的函數式 就可以將數據劫持來觀察數據格式是否正確 ~~~ >[danger] ##### 代碼實現 ~~~ 1.下面實現了一個'trace'方法,這里要說明注意的是,為了能讓trace 更加形象的標記出來對應函數打印的 'console.log',這里在定義的時候會傳兩個參數,但是問題來了,對應的管道中的函數只能接受一個參數, 在執行的時候就會出現代碼錯誤,解決方法同樣我們可以使用'函數的柯里化',將一個多元函數變成一個 一元的函數來解決這種管道問題 ~~~ ~~~ let str = 'jspool'; // 柯里化函數 function curry(func) { return function curriedFn(...args) { // 如果實參小于形參那么就是返回回調函數 if (args.length < func.length) { // 返回函數 return function () { // 將之前函數的參數拼接回來 return curriedFn(...args.concat(Array.from(arguments))) } } // 如果相等返回實際結果 return func(...args) } } // 功能方法用來監控數據變化 const trace = curry((tag, v) => { console.log(tag, v) return v }) const split = (format) => (str) => str.split(format) const reverse = (list) => list.reverse() const join = (format) => (str) => str.join(format) const x = join('') const z = split('') // 仿寫一個函數組合 的管道 function compose(...fns) { return function (val) { // 從右往往左 先反轉 如果不想反轉直接使用reduceRight return fns.reverse().reduce((acc, fn) => { return fn(acc); }, val) } } var fn = compose(x, trace('reverse'), reverse, trace('z'), z) console.log(fn(str)) // loopsj ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看