摘要:循環的函數式改造翻譯自。循環的設計思想深受可變狀態與副作用的影響,不過函數式編程中認為可變狀態與副作用是導致潛在錯誤與不可預測性的罪魁禍首,是應該盡力避免的模式。
JavaScript For 循環的函數式改造翻譯自Rethinking JavaScript: Death of the For Loop。前兩天筆者整理了一篇JavaScript 函數式編程導論,筆者個人不是很喜歡徹底的函數式編程化,在復雜邏輯處理與性能上可能都存在部分問題。不過借鑒函數式編程的思想去改造部分代碼片以提高其可讀性與可測試性還是蠻有好處的,此篇文章以 For-Loop 入手,筆者覺得講得蠻好的。
For 循環的設計思想深受可變狀態與副作用的影響,不過函數式編程中認為可變狀態與副作用是導致潛在錯誤與不可預測性的罪魁禍首,是應該盡力避免的模式。眾所周知,使用全局狀態會污染局部代碼,而同樣的局部狀態同樣會導致與全局狀態一樣的問題,只不過因為局部狀態的影響被限制在較小的影響范圍內,因此不像全局狀態那樣的突兀。允許可變的狀態也就意味著變量可能因為未知的原因被改變,開發者可能要花費數小時的時間去定位到底是哪一段代碼修改了這個變量值。在過去的開發歲月里,我就是因為這樣變禿了,卻似乎沒有變強。
另一方面,任何修改除了作用域內變量值的函數都被稱為有副作用的函數。典型的譬如修改全局變量、讀入鍵盤輸入、調用遠程 API 、寫入磁盤等等。副作用的功效強大,我們應該盡可能地將其封裝與控制在一定范圍內。大道理就回顧到這里,下面我們直接看下代碼:
const cats = [ { name: "Mojo", months: 84 }, { name: "Mao-Mao", months: 34 }, { name: "Waffles", months: 4 }, { name: "Pickles", months: 6 } ] var kittens = [] //典型的 for 循環用法 for (var i = 0; i < cats.length; i++) { if (cats[i].months < 7) { kittens.push(cats[i].name) } } console.log(kittens)
我們改造的第一步是將if語句中的邏輯判斷提取出來,老實說提取之后筆者覺得正好符合Clean JavaScript:寫出整潔的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) } }
這種方式一方面增加了代碼的可用性,另一方面也保證了我們測試條件的可測試性,特別是當我們的邏輯判斷很復雜的時候。下面我們是將屬性提取也抽象出來:
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])) } }
下面我們可以用函數式中的過濾與轉換函數來描述這個過程:
const isKitten = cat => cat.months < 7 const getName = cat => cat.name const kittens = cats.filter(isKitten) .map(getName)
到這里我們摒棄了push函數,即移除了可變狀態的介入。最后的重構即是將我們的過濾與轉換過程再進行一層封裝,使其成為可復用的過程:
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)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81217.html
摘要:典型和改造挑戰了解事件發布訂閱系統實現思想,我們來看一段簡單且典型的基礎實現上面代碼,實現了一個類我們維護一個類型的,對不同事件的所有回調函數進行維護。方法對指定事件進行回調函數存儲方法對指定的觸發事件,逐個執行其回調函數。 showImg(https://segmentfault.com/img/remote/1460000014287200); 新書終于截稿,今天稍有空閑,為大家奉...
摘要:典型和改造挑戰了解事件發布訂閱系統實現思想,我們來看一段簡單且典型的基礎實現上面代碼,實現了一個類我們維護一個類型的,對不同事件的所有回調函數進行維護。方法對指定事件進行回調函數存儲方法對指定的觸發事件,逐個執行其回調函數。 showImg(https://segmentfault.com/img/remote/1460000014287200); 新書終于截稿,今天稍有空閑,為大家奉...
摘要:原文鏈接原文作者函數式編程這篇文章是介紹函數式編程的四篇文章中的第二篇。這些部分被使用的越來越頻繁,人們把他們放到一個函數式編程的庫里面,有一些流行的庫包括未亡待續閱讀下一節原文地址歡迎關注 showImg(https://segmentfault.com/img/bVtSez); tips 原文鏈接: http://jrsinclair.com/articles/2016/gentl...
摘要:作為函數式編程語言,帶來了很多語言上的有趣特性,比如柯里化和反柯里化。在一些函數式編程語言中,會定義一個特殊的占位變量。個人理解不知道對不對延遲執行柯里化的另一個應用場景是延遲執行。不斷的柯里化,累積傳入的參數,最后執行。作為函數式編程語言,JS帶來了很多語言上的有趣特性,比如柯里化和反柯里化。 這里可以對照另外一篇介紹 JS 反柯里化 的文章一起看~ 1. 簡介 柯里化(Currying)...
閱讀 2902·2021-11-23 09:51
閱讀 1547·2021-11-15 11:36
閱讀 3006·2021-10-13 09:40
閱讀 1864·2021-09-28 09:35
閱讀 13040·2021-09-22 15:00
閱讀 1367·2019-08-29 13:56
閱讀 2924·2019-08-29 13:04
閱讀 2699·2019-08-28 18:06