摘要:還是上面函數的例子,我們希望實現下面的形式在下一節具體實現部分應用只傳遞了第一個參數分析上面的代碼可知,實現部分應用的關鍵是部分應用的返回結果是一個新的函數該函數可以被傳入其他參數再次調用柯里化現在進入正題,前面講完了部分應用。
前言
(話不多說,填之前的坑)
正文 引子-從apply說函數應用在js里,我們對于function的用法,可能大部分情況下都還是處于調用,形如
function add(x, y) { return x + y } console.log(add(1, 2)) //函數調用 返回3
但是有一個apply()函數,使我們擁有另一種方式來應用函數,例如
function add(x, y) { return x + y } console.log(add.apply(null, [1, 2])) //返回3
apply的第一個參數為null時,this指向全局對象(忘記請自行查閱查mdn),在上面這個例子里,通過apply來應用函數的時候,效果和調用函數完全一致。
部分應用從前文可知,函數調用就是讓一個參數集合(前面的[1,2])應用到函數(前文的add函數)中,那部分應用就是考慮只傳遞部分參數,而非所有參數。 還是上面add函數的例子,我們希望實現下面的形式(在下一節具體實現):
var newAdd = add.apply(null,[1])//部分應用 只傳遞了第一個參數 newAdd.apply(null,[2]) //3
分析上面的代碼可知,實現部分應用的關鍵是:部分應用的返回結果是一個新的函數,該函數可以被傳入其他參數再次調用
柯里化(curry)現在進入正題,前面講完了部分應用。curry化的含義,就是使函數理解并處理部分應用的過程
繼續按照上文的思路實現add函數的curry化:
function add(x, y) { // 如果只傳遞部分參數,則部分應用,返回一個新的函數 if (y === undefined) { return function (y) { return x + y } } return x + y //如果傳遞所有參數,直接完全應用 } //運行前一節代碼 var newAdd = add.apply(null, [1]) console.log(newAdd.apply(null, [2])) //3 console.log(newAdd.apply(null, [5])) //6
上述代碼已經實現了前一節的要求,可以看到curry的結果就是:經過一次curry的newadd函數,變成一個與1求和的函數,接應用的時候只傳遞一個參數,都能得到對應的結果,同時也可以看出這個curry太局限。接下來我們就要考慮,如何實現通用的curry函數
通用curry函數先回憶前面的過程,來思考curry一個函數的實現步驟:
保存調用curry函數時傳入的參數,返回一個新函數(即柯里化執行結果)
結果函數在被調用后,要讓新的參數和舊的參數一起應用的入參函數中
注:入參函數-要被curry的函數,結果函數-被curry之后的函數*
文字比較抽象,可以直接看實現在回來看過程:
function commonCurry(fn) { var slice = Array.prototype.slice, storedArgs = slice.call(arguments, 1) //使用slice是為了把arguments轉換成真正的數組,剝離此處第一個參數,是因為第一個參數是fn return function () { var newArgs = slice.call(arguments), //新傳入的參數 args = storedArgs.concat(newArgs) return fn.apply(null, args) } } //使用舉例 function add(a, b) { return a + b } var newAdd = commonCurry(add, 10) console.log(newAdd(5)) // 多個參數 function add2(a, b, c, d) { return a + b + c + d } var newAdd2 = commonCurry(add2, 10, 10) console.log(newAdd2(5, 4))//29 // 多次curry var newAdd3 = commonCurry(newAdd2, 10) console.log(newAdd3(10))//40小結
之后會嘗試以更簡潔明了的方式來寫文章。如果內容有錯誤的地方歡迎指出(覺得看著不理解不舒服想吐槽也完全沒問題);如果對你有幫助,歡迎點贊和收藏,轉載請征得同意后著明出處,如果有問題也歡迎私信交流,主頁添加了郵箱地址。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96729.html
摘要:如果你對函數式編程有一定了解,函數柯里化是不可或缺的,利用函數柯里化,可以在開發中非常優雅的處理復雜邏輯。同樣先看簡單版本的方法,以方法為例,代碼來自高級程序設計加強版實現上面函數,可以換成任何其他函數,經過函數處理,都可以轉成柯里化函數。 我們經常說在Javascript語言中,函數是一等公民,它們本質上是十分簡單和過程化的。可以利用函數,進行一些簡單的數據處理,return 結果,...
摘要:作為函數式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。在一些函數式編程語言中,會定義一個特殊的占位變量。個人理解不知道對不對延遲執行柯里化的另一個應用場景是延遲執行。不斷的柯里化,累積傳入的參數,最后執行。作為函數式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying)...
摘要:里也有柯里化的實現,只是平時沒有在意。如果函數柯里化后雖然生搬硬套,不過現實業務也會有類似場景。 柯里化 先解釋下什么是 柯里化 在計算機科學中,柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術。 js 里也有柯里化的實現,只是平時沒有在意。先把原文簡介貼...
摘要:作為函數式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。個人理解不知道對不對延遲執行柯里化的另一個應用場景是延遲執行。不斷的柯里化,累積傳入的參數,最后執行。 作為函數式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying),又稱部分求值(Partial Evalu...
摘要:笑中自動柯里化的精巧實現柯里化是函數式編程中很重要的一環,很多函數式語言都會默認將函數自動柯里化。 什么是柯里化? 在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數且返回結果的新函數的技術。這個技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,盡管...
摘要:一個經常會看到的函數的實現為第一版我們可以這樣使用或者或者已經有柯里化的感覺了,但是還沒有達到要求,不過我們可以把這個函數用作輔助函數,幫助我們寫真正的函數。 JavaScript 專題系列第十三篇,講解函數柯里化以及如何實現一個 curry 函數 定義 維基百科中對柯里化 (Currying) 的定義為: In mathematics and computer science, cu...
閱讀 2806·2021-11-17 09:33
閱讀 4485·2021-09-22 15:57
閱讀 2880·2019-08-30 14:16
閱讀 3144·2019-08-29 14:07
閱讀 2424·2019-08-26 11:55
閱讀 3436·2019-08-23 17:07
閱讀 1734·2019-08-23 16:50
閱讀 2551·2019-08-23 16:08