<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國際加速解決方案。 廣告
                ## js中的函數柯里化(Currying) > 在計算機科學中,柯里化(Currying),又譯為卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術。 > > -- [維基百科](https://en.wikipedia.org/wiki/Currying) > ### 從一道面試題談談函數柯里化 > 題目:使用js實現 add(1)(2)(3)(4) 返回10 > 初次看到這個題目時,我想到的是閉包,因為閉包的定義是:定義在一個函數內部的函數,靜態保存所有了父級作用域的內部函數。所以每次的值可以保存住,到了最后可以全部訪問到。但是想到使用閉包,不知道如何去寫,如果按題所示,不要求后續有無窮,所以可以多嵌套幾層,但是當問題無限擴大時,就不是嵌套可以解決的了,于是我去百度搜索許多關于這方面的知識,今天進行一次總結。 通過函數柯里化的概念,我們可以對其進行處理。 當然下面是初始處理,并不是真正的柯里化。為了方便理解,逐步深入。 ```js //首先我們需要一個入口函數進行基本處理 var add=function(a){ //定義一個保存所有傳入的參數的數組,如果結果是為了求和,則 var result=[]; // 將第一個傳入的參數放置進去 result.push(a); // 定義函數 _add 引用result變量,使其保持不被銷毀掉 var _add=function(b){ // 將參數push進入result中去 result.push(b); // 返回函數 _add 進行下次一調用 return _add; } // 將原生自帶的toString 進行重寫 _add.toString=function(){ console.log(result); return result; } // 返回 _add 函數進行下次調用 return _add; } ``` 執行結果 ```js >>> add(1) >>> [1] >>> ? #<Function> >>> add(1)(2)(3) >>> (3)?[1, 2, 3] >>> ? #<Function> >>> let a=add(1)(2)(3) >>> a >>> (3)?[1, 2, 3] >>> 如果沒有重寫 toString 方法時 >>> add(1) >>> ? (b) { >>> result.push(b); >>> return _add; >>> } ``` 上面函數經過測試,發現返回了result的數組,在這個例子中,最主要的就是 `_add` 函數的問題,如何在調用結束后返回最終的 `result` 值,經過搜索查詢發現了兩個特殊方法,是我們平時最常見的 `toString` 和 `valueOf` 兩個函數,關于這兩個函數的相關信息[鏈接在此](https://segmentfault.com/a/1190000011853909),如果沒有重寫 `toString` 則會輸入函數內容,而不是結果。 在不賦值進行調用時會在游覽器控制臺輸出一個 `? #<Function>` ,目前不知道是什么原因。有知道的麻煩聯系我。當然我在其他博客看到的也有其他一些不知名的提示,可以和下面博客參考著來看 [地址](https://www.cnblogs.com/daisykoo/p/5569619.html) ![基本面基礎思路](images/screenshot_1535697196480.png) ### 真正的函數柯里化 > 柯里化是將接受多個參數轉換為接受一個單一參數來看。 其實在上面的例子中,也可以將所有參數放置進入一個函數的參數中來進行處理,也算是柯里化,但是我們這個例子講真正的js柯里化。 假設你有一個儲錢罐 `countMoney` 函數,和一個記錄本 `arr` 數組,當你每月有空錢時進行儲存,每次在 `arr` 中記錄一次,存入儲錢罐中 ```js var arr=[]; var countMoney=function(arr){ var sum=0; for(var i=0;i<arr.length;i++){ sum+=arr[i]; } return sum; } arr.push(1); arr.push(2); countMoney(arr); ``` 可以通過這種方式來進行存儲,但是有本記錄,是會被發現的,所以這個時候,我們想是否可以這樣 ```js // 每次存儲是調用一次,不需要再次記錄下來 countMoney(1); countMoney(2); // 等到真正需要的時候我們可以直接計算出來這個總值 countMoney(); //3 ``` 于是問題解決的方式變為柯里化問題,需要將多個參數接受轉換為接受單一參數的問題。 于是我們可以使用下面的方式進行處理 ```js var countMoney = (function() { let moneys = 0; let arr = []; var result = function() { // 判斷是否還有參數,如果沒有,則返回存儲起來值的總和 if(arguments.length == 0) { for(var i = 0; i < arr.length; i++) { money += arr[i]; } return money; } else { // arguments 是個類數組來著,應該用展開符展開才能push進去 // 通過arguments 處理可以傳入多個參數值 console.log(...arguments) arr.push(...arguments); return result; } } return result; })(); countMoney(1)(2)(3) countMoney() 6 ``` 上面的例子完全可以實現柯里化,并且進行擴展,現在可以安全的存放錢了。 實際上,在JavaScript的很多思想和設計模式中,閉包是個很常見的且很重要的東西,上面兩個例子代碼中,本質上就是利用了閉包。上面的 `countMoney` 函數是個立即執行的函數,返回一個新函數,而這個新函數實際上就是一個閉包,這個新函數把每次接收到的參數都存儲起來,并且繼續返回一個新函數,當發現某次調用時沒有傳入參數,那就意味著要進行數據統計,從而把之前存儲的數據一次拿出來計算,最后返回計算結果。 當然第一個例子也可以寫成第二個立即執行的這種形式,兩種方式可以互換。 ![柯里化思路](images/screenshot_1535697338335.png) ### 總結 所謂的函數柯里化,亦或是在開發中設計到的其他一些概念。例如閉包、單例模式、觀察者模式等等都好,我們需要關注的點是在于掌握這些模式的設計思想,而不是去死記硬背,比如高大上的模式或者其他的,都是由普通js的技術來構成的,只是因為其設計思想而出現不同質的變化。
                  <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>

                              哎呀哎呀视频在线观看