摘要:三使用場(chǎng)景場(chǎng)景性能優(yōu)化可以將一些模板代碼通過(guò)柯里化的形式預(yù)先定義好,例如這段代碼的作用就是根據(jù)瀏覽器的類型決定事件添加的方式。場(chǎng)景擴(kuò)展能力中的方法,就是通過(guò)柯里化實(shí)現(xiàn)的四總結(jié)通過(guò)本文的介紹,相信你對(duì)柯里化已經(jīng)有一個(gè)全新的認(rèn)識(shí)了。
歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:
柯里化,是函數(shù)式編程的一個(gè)重要概念。對(duì)于沒接觸過(guò)的人來(lái)說(shuō),會(huì)被一串串的小括號(hào)弄得摸不著頭腦。但一旦理解了其中的含義和具體的使用場(chǎng)景,你一定會(huì)對(duì)它愛不釋手。它既能減少代碼冗余,也能增加可讀性,可謂程序猿居家旅行,裝逼撕逼必備之良藥。
二、什么是柯里化如果一個(gè)函數(shù)可以接收多個(gè)參數(shù),將這個(gè)函數(shù)轉(zhuǎn)化為每次只接收一部分參數(shù)的函數(shù)的多次調(diào)用形式,就是柯里化。文字上理解比較困難,先來(lái)看看下面的代碼:
function add(a, b, c) { return a + b + c; }
這個(gè)add函數(shù)接收3個(gè)參數(shù),返回3個(gè)參數(shù)相加的結(jié)果??梢酝ㄟ^(guò)以下2種形式對(duì)其進(jìn)行柯里化:
function addOne(a) { return function(b) { return function(c) { return a + b + c; } } } } function addTwo(a,b) { return function(c) { return a + b + c; } }
執(zhí)行的時(shí)候,以下3種方式都會(huì)獲得一樣的結(jié)果:
add(1, 2, 3); // return 6 addOne(1)(2)(3); // return 6 addTwo(1, 2)(3); // return 6
如果使用ES6語(yǔ)法,能更簡(jiǎn)潔的寫出柯里化后的函數(shù),以addOne為例:
const addOne = (a) => (b) => (c) => (a + b + c)
上面的例子沒有什么實(shí)際的意義,只是為了說(shuō)明概念而已。在了解基本概念后,我們來(lái)聊聊實(shí)際的使用場(chǎng)景。
三、使用場(chǎng)景場(chǎng)景1: 性能優(yōu)化
可以將一些模板代碼通過(guò)柯里化的形式預(yù)先定義好,例如:
var addEvent = function(el, type, fn, capture) { if (window.addEventListener) { el.addEventListener(type, function(e) { fn.call(el, e); }, capture); } else if (window.attachEvent) { el.attachEvent("on" + type, function(e) { fn.call(el, e); }); } }; addEvent(element, "click", handleClick, true);
這段代碼的作用就是根據(jù)瀏覽器的類型決定事件添加的方式。實(shí)際上if...else的判斷只需要進(jìn)行一次。將它柯里化后可以得到以下結(jié)果:
function addCrossBrowserEvent() { if (window.addEventListener) { return function(el, sType, fn, capture) { el.addEventListener(sType, function(e) { fn.call(el, e); }, (capture)); }; } else if (window.attachEvent) { return function(el, sType, fn, capture) { el.attachEvent("on" + sType, function(e) { fn.call(el, e); }); }; } } var addEvent = addCrossBrowserEvent(); addEvent(element, "click", handleClick, true);
場(chǎng)景2: 代碼復(fù)用
在有回調(diào)函數(shù)的場(chǎng)景下,可以通過(guò)柯里化傳入一些預(yù)設(shè)的值,排列組合后,達(dá)到代碼復(fù)用的效果:
// 匹配任何正則的函數(shù) const match = (reg) => (str) => str.match(reg); // 專門匹配空格 const hasSpace = match(/s+/g); // 封裝數(shù)組的 filter 方法 const filter = (fn) => (arr) => arr.filter(fn); // 專門找空格的 filter 方法 const findSpace = filter(hasSpace); // 使用 let result = findSpace(["hi man", "hi_man"]); //["hi man"]
使用傳統(tǒng)的方法實(shí)現(xiàn)以上效果,如下:
let result = ["hi man", "hi_man"].filter( (item) => (item.match(/s+/g)) );
雖然傳統(tǒng)的方法看起來(lái)代碼量比較少,但如果在很多地方需要使用的時(shí)候,就體現(xiàn)出封裝的威力了。而且,還可以為filter方法傳入其它的條件生成各式各樣的find工具函數(shù)!
場(chǎng)景3: 使代碼便于理解
react-redux的connect方法,就是使用了柯里化增加代碼的可讀性:
let Container = connect(mapStateToProps, mapDispatchToProps)(Component);
在這里,connect的作用就是將Component要用到的state切面和action注入到它的property中,達(dá)到展示型組件和容器組件分離的目的。如果將這個(gè)方法的定義改為:
let Container = connect(mapStateToProps, mapDispatchToProps, Component);
就沒那么好理解了。而且,mapStateToProps和mapDispatchToProps實(shí)際上也是可選參數(shù),在不傳它們的情況下傳入Component會(huì)顯得很惡心: connect(null, null, Component)。
場(chǎng)景4: 擴(kuò)展Javascript能力
ES5中的bind方法,就是通過(guò)柯里化實(shí)現(xiàn)的:
if (!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if (typeof this !== "function") { throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function() {}, fBound = function() { return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; if (this.prototype) { fNOP.prototype = this.prototype; } fBound.prototype = new fNOP(); return fBound; }; }四、總結(jié)
通過(guò)本文的介紹,相信你對(duì)柯里化已經(jīng)有一個(gè)全新的認(rèn)識(shí)了。它最少有以下4種功能:
性能優(yōu)化
代碼復(fù)用
使代碼便于理解
擴(kuò)展Javascript能力
靈活使用柯里化,提高代碼質(zhì)量不是夢(mèng)!
P.S. 如果還有本文沒有提到的柯里化用法,歡迎留言交流(^-^)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84963.html
摘要:原文鏈接和都支持函數(shù)的柯里化函數(shù)的柯里化還與的函數(shù)編程有很大的聯(lián)系如果你感興趣的話可以在這些方面多下功夫了解相信收獲一定很多看本篇文章需要知道的一些知識(shí)點(diǎn)函數(shù)部分的閉包高階函數(shù)不完全函數(shù)文章后面有對(duì)這些知識(shí)的簡(jiǎn)單解釋大家可以看看什么是柯里化 原文鏈接 Haskell和scala都支持函數(shù)的柯里化,JavaScript函數(shù)的柯里化還與JavaScript的函數(shù)編程有很大的聯(lián)系,如果你感興...
摘要:作為函數(shù)式編程語(yǔ)言,帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。在一些函數(shù)式編程語(yǔ)言中,會(huì)定義一個(gè)特殊的占位變量。個(gè)人理解不知道對(duì)不對(duì)延遲執(zhí)行柯里化的另一個(gè)應(yīng)用場(chǎng)景是延遲執(zhí)行。不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。作為函數(shù)式編程語(yǔ)言,JS帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。 這里可以對(duì)照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡(jiǎn)介 柯里化(Currying)...
摘要:作為函數(shù)式編程語(yǔ)言,帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。而反柯里化,從字面講,意義和用法跟函數(shù)柯里化相比正好相反,擴(kuò)大適用范圍,創(chuàng)建一個(gè)應(yīng)用范圍更廣的函數(shù)。作為函數(shù)式編程語(yǔ)言,JS帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。 可以對(duì)照另外一篇介紹 JS 柯里化 的文章一起看~ 1. 簡(jiǎn)介 柯里化,是固定部分參數(shù),返回一個(gè)接受剩余參數(shù)的函數(shù),也稱為部分計(jì)算函數(shù),目的是為了縮...
摘要:作為函數(shù)式編程語(yǔ)言,帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。個(gè)人理解不知道對(duì)不對(duì)延遲執(zhí)行柯里化的另一個(gè)應(yīng)用場(chǎng)景是延遲執(zhí)行。不斷的柯里化,累積傳入的參數(shù),最后執(zhí)行。 作為函數(shù)式編程語(yǔ)言,JS帶來(lái)了很多語(yǔ)言上的有趣特性,比如柯里化和反柯里化。 這里可以對(duì)照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡(jiǎn)介 柯里化(Currying),又稱部分求值(Partial Evalu...
摘要:柯里化通用式上面的柯里化函數(shù)沒涉及到高階函數(shù),也不具備通用性,無(wú)法轉(zhuǎn)換形參個(gè)數(shù)任意或未知的函數(shù),我們接下來(lái)封裝一個(gè)通用的柯里化轉(zhuǎn)換函數(shù),可以將任意函數(shù)轉(zhuǎn)換成柯里化。 showImg(https://segmentfault.com/img/remote/1460000018998373); 閱讀原文 前言 在 JavaScript 中,柯里化和反柯里化是高階函數(shù)的一種應(yīng)用,在這之前...
閱讀 3164·2021-11-19 09:40
閱讀 3653·2021-11-16 11:52
閱讀 2984·2021-11-11 16:55
閱讀 3174·2019-08-30 15:55
閱讀 1182·2019-08-30 13:08
閱讀 1659·2019-08-29 17:03
閱讀 3016·2019-08-29 16:19
閱讀 2583·2019-08-29 13:43