摘要:循環(huán)的函數(shù)式改造翻譯自。循環(huán)的設(shè)計(jì)思想深受可變狀態(tài)與副作用的影響,不過(guò)函數(shù)式編程中認(rèn)為可變狀態(tài)與副作用是導(dǎo)致潛在錯(cuò)誤與不可預(yù)測(cè)性的罪魁禍?zhǔn)祝菓?yīng)該盡力避免的模式。
JavaScript For 循環(huán)的函數(shù)式改造翻譯自Rethinking JavaScript: Death of the For Loop。前兩天筆者整理了一篇JavaScript 函數(shù)式編程導(dǎo)論,筆者個(gè)人不是很喜歡徹底的函數(shù)式編程化,在復(fù)雜邏輯處理與性能上可能都存在部分問(wèn)題。不過(guò)借鑒函數(shù)式編程的思想去改造部分代碼片以提高其可讀性與可測(cè)試性還是蠻有好處的,此篇文章以 For-Loop 入手,筆者覺(jué)得講得蠻好的。
For 循環(huán)的設(shè)計(jì)思想深受可變狀態(tài)與副作用的影響,不過(guò)函數(shù)式編程中認(rèn)為可變狀態(tài)與副作用是導(dǎo)致潛在錯(cuò)誤與不可預(yù)測(cè)性的罪魁禍?zhǔn)祝菓?yīng)該盡力避免的模式。眾所周知,使用全局狀態(tài)會(huì)污染局部代碼,而同樣的局部狀態(tài)同樣會(huì)導(dǎo)致與全局狀態(tài)一樣的問(wèn)題,只不過(guò)因?yàn)榫植繝顟B(tài)的影響被限制在較小的影響范圍內(nèi),因此不像全局狀態(tài)那樣的突兀。允許可變的狀態(tài)也就意味著變量可能因?yàn)槲粗脑虮桓淖?,開(kāi)發(fā)者可能要花費(fèi)數(shù)小時(shí)的時(shí)間去定位到底是哪一段代碼修改了這個(gè)變量值。在過(guò)去的開(kāi)發(fā)歲月里,我就是因?yàn)檫@樣變禿了,卻似乎沒(méi)有變強(qiáng)。
另一方面,任何修改除了作用域內(nèi)變量值的函數(shù)都被稱為有副作用的函數(shù)。典型的譬如修改全局變量、讀入鍵盤(pán)輸入、調(diào)用遠(yuǎn)程 API 、寫(xiě)入磁盤(pán)等等。副作用的功效強(qiáng)大,我們應(yīng)該盡可能地將其封裝與控制在一定范圍內(nèi)。大道理就回顧到這里,下面我們直接看下代碼:
const cats = [ { name: "Mojo", months: 84 }, { name: "Mao-Mao", months: 34 }, { name: "Waffles", months: 4 }, { name: "Pickles", months: 6 } ] var kittens = [] //典型的 for 循環(huán)用法 for (var i = 0; i < cats.length; i++) { if (cats[i].months < 7) { kittens.push(cats[i].name) } } console.log(kittens)
我們改造的第一步是將if語(yǔ)句中的邏輯判斷提取出來(lái),老實(shí)說(shuō)提取之后筆者覺(jué)得正好符合Clean JavaScript:寫(xiě)出整潔的JavaScript代碼里面提及的讓變量名而不是注釋表述其含義的效果:
const isKitten = cat => cat.months < 7 var kittens = [] for (var i = 0; i < cats.length; i++) { if (isKitten(cats[i])) { kittens.push(cats[i].name) } }
這種方式一方面增加了代碼的可用性,另一方面也保證了我們測(cè)試條件的可測(cè)試性,特別是當(dāng)我們的邏輯判斷很復(fù)雜的時(shí)候。下面我們是將屬性提取也抽象出來(lái):
const isKitten = cat => cat.months < 7 const getName = cat => cat.name var kittens = [] for (var i = 0; i < cats.length; i++) { if (isKitten(cats[i])) { kittens.push(getName(cats[i])) } }
下面我們可以用函數(shù)式中的過(guò)濾與轉(zhuǎn)換函數(shù)來(lái)描述這個(gè)過(guò)程:
const isKitten = cat => cat.months < 7 const getName = cat => cat.name const kittens = cats.filter(isKitten) .map(getName)
到這里我們摒棄了push函數(shù),即移除了可變狀態(tài)的介入。最后的重構(gòu)即是將我們的過(guò)濾與轉(zhuǎn)換過(guò)程再進(jìn)行一層封裝,使其成為可復(fù)用的過(guò)程:
const isKitten = cat => cat.months < 7 const getName = cat => cat.name const getKittenNames = cats => cats.filter(isKitten) .map(getName) const cats = [ { name: "Mojo", months: 84 }, { name: "Mao-Mao", months: 34 }, { name: "Waffles", months: 4 }, { name: "Pickles", months: 6 } ] const kittens = getKittenNames(cats) console.log(kittens)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81217.html
摘要:典型和改造挑戰(zhàn)了解事件發(fā)布訂閱系統(tǒng)實(shí)現(xiàn)思想,我們來(lái)看一段簡(jiǎn)單且典型的基礎(chǔ)實(shí)現(xiàn)上面代碼,實(shí)現(xiàn)了一個(gè)類(lèi)我們維護(hù)一個(gè)類(lèi)型的,對(duì)不同事件的所有回調(diào)函數(shù)進(jìn)行維護(hù)。方法對(duì)指定事件進(jìn)行回調(diào)函數(shù)存儲(chǔ)方法對(duì)指定的觸發(fā)事件,逐個(gè)執(zhí)行其回調(diào)函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000014287200); 新書(shū)終于截稿,今天稍有空閑,為大家奉...
摘要:典型和改造挑戰(zhàn)了解事件發(fā)布訂閱系統(tǒng)實(shí)現(xiàn)思想,我們來(lái)看一段簡(jiǎn)單且典型的基礎(chǔ)實(shí)現(xiàn)上面代碼,實(shí)現(xiàn)了一個(gè)類(lèi)我們維護(hù)一個(gè)類(lèi)型的,對(duì)不同事件的所有回調(diào)函數(shù)進(jìn)行維護(hù)。方法對(duì)指定事件進(jìn)行回調(diào)函數(shù)存儲(chǔ)方法對(duì)指定的觸發(fā)事件,逐個(gè)執(zhí)行其回調(diào)函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000014287200); 新書(shū)終于截稿,今天稍有空閑,為大家奉...
摘要:原文鏈接原文作者函數(shù)式編程這篇文章是介紹函數(shù)式編程的四篇文章中的第二篇。這些部分被使用的越來(lái)越頻繁,人們把他們放到一個(gè)函數(shù)式編程的庫(kù)里面,有一些流行的庫(kù)包括未亡待續(xù)閱讀下一節(jié)原文地址歡迎關(guān)注 showImg(https://segmentfault.com/img/bVtSez); tips 原文鏈接: http://jrsinclair.com/articles/2016/gentl...
摘要:作為函數(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)...
閱讀 2912·2021-11-23 09:51
閱讀 1561·2021-11-15 11:36
閱讀 3018·2021-10-13 09:40
閱讀 1913·2021-09-28 09:35
閱讀 13097·2021-09-22 15:00
閱讀 1380·2019-08-29 13:56
閱讀 2933·2019-08-29 13:04
閱讀 2706·2019-08-28 18:06