第一次看到柯里化這個詞的時候,還是在看一篇演算法相關的部落格提到把函式柯里化,那時一看這個詞就感覺很高階,實際上當你了解了後才發現其實就是高階函式的乙個特殊用法。
果然是不管作用怎麼樣都要有個高階的名字才有用。
維基百科上說道:柯里化,英語:currying(果然是滿滿的英譯中的既視感),是把接受多個引數的函式變換成接受乙個單一引數(最初函式的第乙個引數)的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。看這個解釋有一點抽象,我們就拿被做了無數次示例的add函式,來做乙個簡單的實現。
// 普通的add函式
function add(x, y)
// currying後
function curryingadd(x)
}add(1, 2) // 3
curryingadd(1)(2) // 3
實際上就是把add函式的x,y兩個引數變成了先用乙個函式接收x然後返回乙個函式去處理y引數。現在思路應該就比較清晰了,就是只傳遞給函式一部分引數來呼叫它,讓它返回乙個函式去處理剩下的引數。
但是問題來了費這麼大勁封裝一層,到底有什麼用處呢?沒有好處想讓我們程式設計師多幹事情是不可能滴,這輩子都不可能.
1. 引數復用
// 正常正則驗證字串 reg.test(txt)
// 函式封裝後
function check(reg, txt)
check(/\d+/g, 'test') //false
check(/[a-z]+/g, 'test') //true
// currying後
function curryingcheck(reg)
}var hasnumber = curryingcheck(/\d+/g)
var hasletter = curryingcheck(/[a-z]+/g)
hasnumber('test1') // true
hasnumber('testtest') // false
hasletter('21212') // false
上面的示例是乙個正則的校驗,正常來說直接呼叫check函式就可以了,但是如果我有很多地方都要校驗是否有數字,其實就是需要將第乙個引數reg進行復用,這樣別的地方就能夠直接呼叫hasnumber,hasletter等函式,讓引數能夠復用,呼叫起來也更方便。
2. 提前確認
var on = function(element, event, handler)
} else
}}var on = (function()
};} else };}
})();
//換一種寫法可能比較好理解一點,上面就是把issupport這個引數給先確定下來了
var on = function(issupport, element, event, handler) else
}
我們在做專案的過程中,封裝一些dom操作可以說再常見不過,上面第一種寫法也是比較常見,但是我們看看第二種寫法,它相對一第一種寫法就是自執行然後返回乙個新的函式,這樣其實就是提前確定了會走哪乙個方法,避免每次都進行判斷。
3. 延遲執行
function.prototype.bind = function (context)
}
像我們js中經常使用的bind,實現的機制就是currying.
說了這幾點好處之後,發現還有個問題,難道每次使用currying都要對底層函式去做修改,
// 初步封裝
var currying = function(fn)
}
這邊首先是初步封裝,通過閉包把初步引數給儲存下來,然後通過獲取剩下的arguments進行拼接,最後執行需要currying的函式。
但是好像還有些什麼缺陷,這樣返回的話其實只能多擴充套件乙個引數,currying(a)(b)(c)這樣的話,貌似就不支援了(不支援多引數呼叫),一般這種情況都會想到使用遞迴再進行封裝一層。
// 支援多引數傳遞
function progresscurrying(fn, args)
// 引數收集完畢,則執行fn
}}
這邊其實是在初步的基礎上,加上了遞迴的呼叫,只要引數個數小於最初的fn.length,就會繼續執行遞迴。
curry的一些效能問題你只要知道下面四點就差不多了:
其實在大部分應用中,主要的效能瓶頸是在操作dom節點上,這js的效能損耗基本是可以忽略不計的,所以curry是可以直接放心的使用。
// 實現乙個add方法,使計算結果能夠滿足如下預期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() ;
// 利用tostring隱式轉換的特性,當最後執行時隱式轉換,並計算最終的值返回
_adder.tostring = function () );
}return _adder;
}add(1)(2)(3) // 6
add(1, 2, 3)(4) // 10
add(1)(2)(3)(4)(5) // 15
add(2, 6)(1) // 9
詳解JS函式柯里化
第一次看到柯里化這個詞的時候,還是在看一篇演算法相關的部落格提到把函式柯里化,那時一看這個詞就感覺很高階,實際上當你了解了後才發現其實就是高階函式的乙個特殊用法。果然是不管作用怎麼樣都要有個高階的名字才有用。維基百科上說道 柯里化,英語 currying 果然是滿滿的英譯中的既視感 是把接受多個引數...
js函式柯里化
什麼是函式柯里化?在電腦科學中,柯里化 currying 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。這個技術由 christopher strachey 以邏輯學家 haskell curry 命名的,儘管它是 mos...
js 函式柯里化
函式柯里化的主要目的就是為了減少函式傳參,同時將一些固定引數私有化。下面展示一段非常簡單計算圓面積的 來說明函式柯里化的原理 circle函式,接受半徑r和 function circle r,p 通過函式柯里化來簡化circle函式,只傳入半徑就能計算出面積 不管怎麼樣,是不會變的,因此我們將他寫...