<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國際加速解決方案。 廣告
                >[success] # 函數柯里化 1. **柯里化**也是屬于**函數式編**程里面一個**概念** 2. **js 設計模式與開發實踐書中的解釋**:currying又稱部分求值。一個currying的函數首先會接受一些參數,接受了這些參數之后,該函數并不會立即求值,而是繼續返回另外一個函數, 剛才傳入的參數在函數形成的閉包中被保存起來。待到函數被真正需要求值的時候, 之前傳入的所有參數都會被一次性用于求值。 3. **js高級程序語言設計**與函數綁定緊密相關的主題是函數柯里化,它用于創建已經設置好了一個或多個參數的函數。 函數柯里化的基本方法和函數綁定是一樣的:使用一個閉包返回一個函數。兩者的區別在于,當函數被調用時,返回的函數還需要設置一些傳入的參數 * 總結:當一個函數有多個參數的時候先傳遞一部分參數調用它(**這部分參數以后永遠不變**),然后返回一個新的函數接收剩余的參數,返回結果 **柯理化函數思想**:預先存儲(預處理),利用閉包的“保存機制”,我們把一些值事先存儲起來,供其下級上下文中后期用 * **舉個例子**柯里化是一種函數的轉換,將一個函數從可調用的**f(a, b, c)** 轉換為可調用的 **f(a)(b)(c)**,柯里化不會調用函數。它只是對函數進行轉換。 ~~~ // 基于console.log或者alert輸出一個函數,會默認先把函數轉化為字符串「Symbol.toPrimitive -> valueOf -> toString」 const curring = function curring() { let params = []; // 利用閉包 const add = (...args) => { params = params.concat(args); // 將每一次調用參數都存儲在閉包外部作用域函數的參數中 return add; }; add[Symbol.toPrimitive] = () => params.reduce((result, item) => result + item); return add; }; let add = curring(); let res = add(1)(2)(3); console.log(res); //->6 add = curring(); res = add(1, 2, 3)(4); console.log(res); //->10 add = curring(); res = add(1)(2)(3)(4)(5); console.log(res); //->15 ~~~ >[info] ## 柯里化優勢 1. **函數的職責單一**,實際編程中望一個函數處理的問題盡可能的單一,而不是將一大堆的處理過程交給一個函數來處理 2. **函數的參數服用**,某些情況下可以復用參數邏輯 >[danger] ##### 參數復用案例 ~~~ function checkAag(age) { let min = 18 return age >= min } // 上面定義的min 參數讓整個函數變得局限只能針對18來做來做判斷 // 現在思路升級定義兩個參數,讓整個方法更加靈活 function checkAag(min, age) { return age >= min } // 都是18的基準值被反復傳參 checkAge(18, 24) checkAge(18, 20) checkAge(20, 30) // ---------------------------柯里化解決--------------------------- // 柯里化是閉包的應用場景之一,他利用了閉包延長作用域的這個特性 // 將 把接受多個參數的函數變換成接受一個單一參數的函數,并且返回接受余下的參數且返回結果的新函數 // 以上面的案例來分析 我們會先傳min 這參數,他會返回一個新的函數,這個新的函數會接受age參數返回我們想要的結果 const { log } = console function checkAge(min) { return function (age) { return age >= min } } // 解決了剛才同一個基準值反復 傳參的問題 let checkAge18 = checkAge(18) let checkAge20 = checkAge(20) log(checkAge20(19)) // false log(checkAge18(16)) // false // ES6 寫法 let checkAge = min => (age => age >= min) ~~~ >[info] ## 柯里化推到 >[danger] ##### 拓展思維逐步柯里化(一) ~~~ // 計算每天花銷的錢(最傳統的寫法) let monthlyCost = 0 var cost = function (money) { monthlyCost += money } cost(100) cost(200) // 300 console.log(monthlyCost) ~~~ ~~~ 1.現在雖然用了閉包,比剛才的效果更好,并且已經形成了一個函數式的編程,準確的說已經形成一個 純函數,因為此時已經不存在副作用 2.按照柯里化的概念來說,我們可以控制真正想要結果的時機,但是現在明顯不可以,每次執行都會 得到一個結果,當前需求實際只想要七天的總和而不是中間步驟每一次結果 ~~~ ~~~ // 利用閉包 把 monthlyCost 作用域限制在函數內 var cost = (function () { let monthlyCost = 0 return function () { monthlyCost += [].shift.apply(arguments) return monthlyCost } })() cost(100) console.log(cost(200)) // 300 ~~~ >[danger] ##### 拓展思維逐步柯里化(二) ~~~ 1.上面兩個雖然都滿足就算每個禮拜的價格花銷,要做的只是不停的調用 七次,如果讓計算平均值,計算一個月呢? 2.在看一下函數柯里化的概念,先傳遞一部分參數,但是不會返回結果而是一個函數, 當想要的剩余參數全部都接受完了,此時才會返回想要的結果,下面案例是有點特殊,是 不傳參數時候才會返回結果,形成的整理思路還是一樣,只有想要執行結果的時候才會觸發 ~~~ * 做到第一步我們只關心結果不關心過程值 ~~~ var cost = (function () { let args = [] return function () { if(arguments.length === 0){ return args.reduce((accumulator, currentValue) => accumulator+currentValue) }else{ [].push.apply(args,arguments) } } })() cost(100) console.log(cost(200)) console.log(cost()) // 300 ~~~ >[danger] ##### 最終柯里化寫法 ~~~ 1.這種最終寫法完成符合柯里化函數的定義 ~~~ ~~~ var currying = function (fn) { let args = [] return function () { if(arguments.length === 0){ return fn.apply(this,args) // 你想給一個方法傳入多個參數用apply 小技巧當然es6用展開操運算'...' }else{ // 如果不是想執行計算的時候就返回代碼本身 [].push.apply(args,arguments) return arguments.callee } } } // 通過計算總和的函數,如果不需要總和就寫對應條件的函數即可 var cost = function () { return [].reduce.call(arguments,(accumulator, currentValue) => accumulator+currentValue) } var cost = currying(cost) // 因為返回的是本身所以可以這么寫 //cost(100)(200) // 也可以下面這么寫一直調用 cost(100) cost(200) console.log(cost()) // 300 ~~~ >[info] ## lodash 中的柯里化函數 ~~~ 1.lodash 利用的就是函數式編程的思想,其中提供的'curry'方法可以將函數轉成柯里化函數,關于lodash 這個方法使用的講解: 功能:創建一個函數,該函數接收一個或多個 func 的參數,如果 func 所需要的參數都被提 供則執行 func 并返回執行的結果。否則繼續返回該函數并等待接收剩余的參數。 參數:需要柯里化的函數 返回值:柯里化后的函數 ~~~ >[danger] ##### 使用 一 ~~~ // 引入lodash const _ = require('lodash') // 創建一個函數 function getSum(a, b, c) { return a + b + c } // 使用curry 將getSum 轉換成柯里化函數 let curried = _.curry(getSum) // 把接受多個參數的函數變換成接受一個單一參數的函數,并且返回接受余下的參數且返回結果的新函數 curried(1, 2, 3) // 直接執行 curried(1)(2)(3) // (1) 和 (2) 都沒有直接返回結果 只有形成個數和實參一直時執行符合柯里化 // 利用柯里化將函數轉成了一元函數,原本是要傳三個參數,在(1,2)返回的新的函數只要傳一個參數 curried(1, 2)(3) ~~~ >[danger] ##### 使用二 ~~~ 1.現在要對一個每一項是字符串組成的數組進行過濾找到,不包含空字符串的字符項 ~~~ ~~~ const _ = require('lodash') // 先柯里化 查找規則的函數 const match = _.curry(function (reg, str) { return str.match(reg) }) // 使用柯里化定義規則 const haveSpace = match(/\s+/g) // 使用柯里化創建一個數組過濾方法 const filter = _.curry(function (func, array) { return array.filter(func) }) // 使用柯里化并將比價規則的柯里化函數作為回調傳入 const findSpace = filter(haveSpace) // ------------執行------------- console.log(filter(haveSpace, ['John Connor', 'John_Donne'])) console.log(findSpace(['John Connor', 'John_Donne'])) ~~~ >[danger] ##### 實現一個curry 函數 ~~~ 1.拋開lodash這種現成封裝好的函數庫,自己如何實現一個柯里化轉換函數,主要的思路就是 要知道形參和實參是否在長度上已經相等,不相等就不會返回結果,相等則會返回對應結果內容 ~~~ [關于函數形參長度](http://www.hmoore.net/cyyspring/more/1441815) ~~~ // 將函數柯里化 function curry(func) { return function curriedFn(...args) { // 如果實參小于形參那么就是返回回調函數 if (args.length < func.length) { // 返回函數 return function () { // 將之前函數的參數拼接回來 return curriedFn(...args.concat(Array.from(arguments))) } } // 如果相等返回實際結果 return func(...args) } } function getSum(a, b, c) { return a + b + c } const curried = curry(getSum) console.log(curried(1, 2, 3)) //6 console.log(curried(1)(2, 3)) //6 console.log(curried(1, 2)(3)) // 6 ~~~ >[info] ## 對柯里化的總結 ~~~ 1.柯里化可以讓我們給一個函數傳遞較少的參數得到一個已經記住了某些固定參數的新函數 2.這是一種對函數參數的'緩存' 本質上就是利用閉包 3.讓函數變的更靈活,讓函數的粒度更小 4.可以把多元函數轉換成一元函數 ~~~
                  <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>

                              哎呀哎呀视频在线观看