合理純粹的功能編程簡介
鑰匙要點
- 純函數在功能編程中至關重要,因為它們返回相同輸入的相同輸出而不會引起副作用,增強可預測性和可檢驗性。 通過將過程分解為更簡單,不可變的函數, 功能編程可降低程序的複雜性,從而有助於最大程度地減少錯誤並改善代碼可讀性。
- > 在功能編程中 過度反應,同時降低代碼複雜性,可能會導致難以理解和維護的代碼,從而突出餘額的重要性。
- > >基本的JavaScript函數,例如`map',``reade','',``過濾''和`compose'至關重要,對於採用功能編程範式並促進創建更簡潔和聲明的代碼。
- 測試具有純粹的功能變得更加簡單,因為它們的孤立性質允許更輕鬆的測試條件和預期結果設置。 >功能編程不僅是一個理論概念,而且適用於處理異步操作和UI更新等實際情況,它在現代網絡開發中證明了它的相關性。
- >
- 本文由Panayiotis«Pvgr»Velisarakos,Jezen Thomas和Florian Rappl進行了同行評審。感謝SitePoint所有的同行評審員製作SitePoint內容的最佳功能! 在學習編程時,您首先介紹了程序編程;在這裡,您可以通過向其饋送命令的順序列表來控制機器。 在了解一些語言基本原理之後,例如變量,作業,功能和對象,您可以將一個程序拼湊而成,可以實現您為此做出的工作 - 您感覺就像是絕對的嚮導。
。 當您成為更好的程序員時,您會編寫較小的功能,更好地重複使用代碼,為您的代碼編寫測試,並相信您編寫的程序將繼續按照您的意圖進行。 沒有人喜歡在代碼中查找和修復錯誤,因此成為更好的程序員也是要避免某些容易出錯的事情。 通過經驗或聽取經驗豐富的人的建議來避免什麼,例如道格拉斯·克羅克福德(Douglas Crockford)在JavaScript中著名地解釋了:
。功能編程為我們提供了通過將程序簡化為最簡單的形式來降低程序複雜性的方法:表現得像純數學功能的功能。 學習功能編程的原理是您技能集的一個很好的補充,它將幫助您使用更少的錯誤編寫更簡單的程序。
功能編程的關鍵概念是純粹的函數,不可變的值,組成和馴服副作用。
純函數
純函數是一個函數,給定相同的輸入將始終返回相同的輸出,並且沒有任何可觀察到的副作用。
<span>// pure </span><span>function add(a<span>, b</span>) { </span> <span>return a + b; </span><span>} </span>
純。它不依賴或更改功能之外的任何狀態,它將始終>始終返回相同輸入的相同輸出值。
此函數是<span>// impure </span><span>var minimum = 21; </span><span>var checkAge = function(age) { </span> <span>return age >= minimum; // if minimum is changed we're cactus </span><span>}; </span>
,因為它依賴於功能之外的外部可突變狀態。 如果我們將此變量移入功能的內部,它將變得純淨,我們可以確定我們的函數將正確檢查我們的年齡
。純函數沒有側面效應
。這裡有一些重要的要記住:<span>// pure </span><span>var checkAge = function(age) { </span> <span>var minimum = 21; </span> <span>return age >= minimum; </span><span>}; </span>
>訪問函數之外的系統狀態
突變對像作為參數- 進行HTTP調用
- 獲得用戶輸入
- 查詢DOM
- 受控突變
- >您需要意識到改變底部對象的數組和對像上的突變器方法,一個例子是數組的剪接和切片方法之間的差異。
>如果我們避免在傳遞給我們功能的對像上突變方法,我們的程序變得更容易推理,我們可以合理地期望我們的功能不要從我們的下面切換出來。
純函數的好處
<span>// impure, splice mutates the array </span><span>var firstThree = function(arr) { </span> <span>return arr.splice(0,3); // arr may never be the same again </span><span>}; </span> <span>// pure, slice returns a new array </span><span>var firstThree = function(arr) { </span> <span>return arr.slice(0,3); </span><span>}; </span>
純粹的功能對其不純淨的對應物有一些好處:
<span>let items = ['a','b','c']; </span><span>let newItems = pure(items); </span><span>// I expect items to be ['a','b','c'] </span>
>結果是可以緩存的,因為相同的輸入始終產生相同的輸出
>>自我記錄,因為該函數的依賴項是明確的
- >更易於使用,因為您不必擔心副作用
- 由於純函數的結果是可緩存的,所以我們可以記住它們,因此僅在調用功能時才執行昂貴的操作。 例如,回憶搜索大型索引的結果將在重新運行時產生重大績效的改進。
- 不合理的純粹功能編程 將我們的程序降低到純粹的功能可以大大降低我們程序的複雜性。但是,如果我們將功能抽象推得太遠,我們的功能性計劃也可能最終需要Rain Man的幫助來理解。
>
>除非您具有功能編程背景這些抽象(咖哩,過度使用組合和道具),這確實是很難遵循的,而執行流也是如此。 下面的代碼更容易理解和修改,它也比上面純粹的功能方法更清楚地描述了程序。
- 應用程序函數採用一串標籤
- >從flickr
- 獲取JSON 將url刪除響應
- 構建
- 將它們插入文檔
- >
<span>// pure </span><span>function add(a<span>, b</span>) { </span> <span>return a + b; </span><span>} </span>
>
<span>// impure </span><span>var minimum = 21; </span><span>var checkAge = function(age) { </span> <span>return age >= minimum; // if minimum is changed we're cactus </span><span>}; </span>
ajax請求和dom操作永遠不會純粹,但是我們可以從其餘的純粹的功能中發揮出純粹的功能,將響應json映射到一系列圖像中 - 讓我們暫時求依賴對jQuery的依賴。
>我們的功能現在只是在做兩件事:
<span>// pure </span><span>var checkAge = function(age) { </span> <span>var minimum = 21; </span> <span>return age >= minimum; </span><span>}; </span>
映射響應數據 - > URL
- 映射URL->圖像
- >“功能”方法是為這兩個任務創建單獨的函數,我們可以使用組合將一個函數的響應傳遞到另一個函數中。
撰寫返回一個函數列表組成的函數,每個函數都消耗了隨後的函數的返回值。
<span>// impure, splice mutates the array </span><span>var firstThree = function(arr) { </span> <span>return arr.splice(0,3); // arr may never be the same again </span><span>}; </span> <span>// pure, slice returns a new array </span><span>var firstThree = function(arr) { </span> <span>return arr.slice(0,3); </span><span>}; </span>
>有助於閱讀參數以從右到左構成以了解數據流的方向。這是組成的作品,將URL的響應傳遞到我們的圖像功能中。
,這當然不是我們想要的。 詢問重構代碼時最重要的問題是:
<span>let items = ['a','b','c']; </span><span>let newItems = pure(items); </span><span>// I expect items to be ['a','b','c'] </span>
>
基本函數>現在,我根本不是要攻擊功能編程。每個開發人員都應進行一致的努力來學習基本功能,使您在編程中抽象共同的模式,以更簡潔的聲明代碼,或者正如Marijn Haverbeke所說的那樣。
>具有基本功能曲目的程序員,更重要的是,關於如何使用它們的知識比從頭開始的人更有效。 - 雄辯的JavaScript,Marijn Haverbeke
這是每個JavaScript開發人員都應該學習和掌握的基本功能的列表。這也是一種掌握JavaScript技能的好方法,可以從頭開始編寫這些功能。
- foreach
- 地圖
- >過濾
- 降低
- debounce
- 組成
- 部分
- 咖哩
>讓我們看一些可以使用功能編程概念來改進代碼的實用步驟。
<span>// pure </span><span>function add(a<span>, b</span>) { </span> <span>return a + b; </span><span>} </span>
這聽起來可能很明顯,但我仍然編寫訪問和修改許多狀態的功能,這使它們更難測試,並且更容易出錯。
使用更可讀的語言摘要,例如foreach to Iterate
<span>// impure </span><span>var minimum = 21; </span><span>var checkAge = function(age) { </span> <span>return age >= minimum; // if minimum is changed we're cactus </span><span>}; </span>
使用更高級別的抽象(例如地圖)來減少代碼
<span>// pure </span><span>var checkAge = function(age) { </span> <span>var minimum = 21; </span> <span>return age >= minimum; </span><span>}; </span>
將功能降低到其最簡單的形式
<span>// impure, splice mutates the array </span><span>var firstThree = function(arr) { </span> <span>return arr.splice(0,3); // arr may never be the same again </span><span>}; </span> <span>// pure, slice returns a new array </span><span>var firstThree = function(arr) { </span> <span>return arr.slice(0,3); </span><span>}; </span>
刪除代碼,直到停止工作
<span>let items = ['a','b','c']; </span><span>let newItems = pure(items); </span><span>// I expect items to be ['a','b','c'] </span>
>我們根本不需要一個功能來完成如此簡單的任務,該語言為我們提供了足夠的抽象來逐字寫出。
測試
<span>import _ from 'ramda'; </span><span>import $ from 'jquery'; </span> <span>var Impure = { </span> <span>getJSON: _.curry(function(callback<span>, url</span>) { </span> $<span>.getJSON(url, callback); </span> <span>}), </span> <span>setHtml: _.curry(function(sel<span>, html</span>) { </span> <span>$(sel).html(html); </span> <span>}) </span><span>}; </span> <span>var img = function (url) { </span> <span>return $('<img />', { src: url }); </span><span>}; </span> <span>var url = function (t) { </span> <span>return 'http://api.flickr.com/services/feeds/photos_public.gne?tags=' + </span> t <span>+ '&format=json&jsoncallback=?'; </span><span>}; </span> <span>var mediaUrl = _.compose(_.prop('m'), _.prop('media')); </span><span>var mediaToImg = _.compose(img, mediaUrl); </span><span>var images = _.compose(_.map(mediaToImg), _.prop('items')); </span><span>var renderImages = _.compose(Impure.setHtml("body"), images); </span><span>var app = _.compose(Impure.getJSON(renderImages), url); </span><span>app("cats"); </span>
>
>啟動終端,並準備好您的文本編輯器,我們將使用摩卡咖啡作為測試跑步者,而babel來編譯我們的ES6代碼。
>摩卡具有許多方便的功能,例如描述,它可以分解我們的測試和掛鉤,例如以前和之後進行設置和拆除任務。 斷言是一個可以執行簡單平等測試,斷言和斷言的核心節點軟件包。 DeepEqual是最有用的功能。
>讓我們在test/example.js<span>var app = (tags)=> { </span> <span>let url = <span>`http://api.flickr.com/services/feeds/photos_public.gne?tags=<span>${tags}</span>&format=json&jsoncallback=?`</span> </span> $<span>.getJSON(url, (data)=> { </span> <span>let urls = data.items.map((item)=> item.media.m) </span> <span>let images = urls.map((url)=> $('<img />', { src: url }) ) </span> <span>$(document.body).html(images) </span> <span>}) </span><span>} </span><span>app("cats") </span>
>打開軟件包。
然後,您應該能夠從命令行運行NPM測試,以確認所有內容都是按預期工作的。
><span>let flickr = (tags)=> { </span> <span>let url = <span>`http://api.flickr.com/services/feeds/photos_public.gne?tags=<span>${tags}</span>&format=json&jsoncallback=?`</span> </span> <span>return fetch(url) </span> <span>.then((resp)=> resp.json()) </span> <span>.then((data)=> { </span> <span>let urls = data.items.map((item)=> item.media.m ) </span> <span>let images = urls.map((url)=> $('<img />', { src: url }) ) </span> <span>return images </span> <span>}) </span><span>} </span><span>flickr("cats").then((images)=> { </span> <span>$(document.body).html(images) </span><span>}) </span>
boom。
<span>let responseToImages = (resp)=> { </span> <span>let urls = resp.items.map((item)=> item.media.m ) </span> <span>let images = urls.map((url)=> $('<img />', { src: url })) </span> <span>return images </span><span>} </span>
>
<span>let urls = (data)=> { </span> <span>return data.items.map((item)=> item.media.m) </span><span>} </span><span>let images = (urls)=> { </span> <span>return urls.map((url)=> $('<img />', { src: url })) </span><span>} </span><span>let responseToImages = _.compose(images, urls) </span>
讓我們將模塊添加到lib/flickr.js
<span>let responseToImages = (data)=> { </span> <span>return images(urls(data)) </span><span>} </span>
>
>我們有幾個新的依賴性:jQuery,下劃線和polyfills以獲取和承諾。 為了測試那些我們可以使用jsdom將DOM對象窗口和文檔進行多填充,我們可以使用Sinon軟件包來固定fetch api。<span>// pure </span><span>function add(a<span>, b</span>) { </span> <span>return a + b; </span><span>} </span>
>打開test/_setup.js,我們將使用模塊依賴的Globals配置JSDOM。
<span>// impure </span><span>var minimum = 21; </span><span>var checkAge = function(age) { </span> <span>return age >= minimum; // if minimum is changed we're cactus </span><span>}; </span>
>
<span>// pure </span><span>var checkAge = function(age) { </span> <span>var minimum = 21; </span> <span>return age >= minimum; </span><span>}; </span>
ph!我們已經成功測試了我們的小模塊以及構成它的功能,了解純粹的功能以及如何在此過程中使用功能組合物。 我們已經將純淨的純度分開,它是可讀的,由小功能組成,並且經過了經過良好的測試。 代碼比上面的不合理的純
<span>// impure, splice mutates the array </span><span>var firstThree = function(arr) { </span> <span>return arr.splice(0,3); // arr may never be the same again </span><span>}; </span> <span>// pure, slice returns a new array </span><span>var firstThree = function(arr) { </span> <span>return arr.slice(0,3); </span><span>}; </span>
,這是我在重構代碼時的唯一目標。 純函數,使用它們。 > 鏈接
> Frisby教授的功能編程大多數指南 - @drboolean - Brian Lonsdorf的這本出色的有關功能編程的免費書籍是我遇到的FP的最佳指南。 本文中的許多想法和示例來自本書。
>雄辯的JavaScript - 功能編程@marijnjh - Marijn Haverbeke的書仍然是我一直以來最喜歡的編程介紹之一,並且在功能編程方面也有很棒的章節。
>- 下劃線 - 挖掘諸如下劃線,lodash或ramda之類的公用事業庫是作為開發人員成熟的重要一步。了解如何使用這些功能將大大減少您需要編寫的代碼數量,並使您的程序更具聲明性。
- -
- 就目前而言! 感謝您的閱讀,希望您能在JavaScript中對功能編程,重構和測試的良好介紹。 這是一個有趣的範式,目前正在引起浪潮,這主要是由於諸如React,Redux,Elm,Cycle和Reactivex等庫的日益普及,它鼓勵或強制執行這些模式。
- 跳進去,水很溫暖。
純函數在功能編程中的重要性是什麼?它們是始終為相同輸入產生相同輸出的功能,並且沒有副作用。這意味著他們不會改變範圍之外的任何狀態或依賴任何外部狀態。這使它們可以預測且易於測試,因為您只需要考慮輸入和輸出而不必擔心外部因素。純函數還可以促進代碼可重複性和可讀性,使您的代碼易於理解和維護。
功能編程與其他編程範式有何不同?
功能編程是一種編程範式,它將計算視為評估數學函數並避免變化狀態和可變數據。這與當務之急的編程形成對比,該程序由執行時改變全局狀態的陳述組成。功能編程促進了高級抽象,例如作為一流公民的功能,並鼓勵用表達方式而不是語句進行編程。這會導致更易於推理的聲明性和表現力的編程風格。>
>如何在JavaScript中實現純函數?>產生相同輸入的相同輸出,並且不會產生任何副作用。以下是一個示例:
函數add(a,b){
返回a b;
}
在此示例中,添加函數是純函數,因為它始終返回在相同的參數的情況下,相同的結果也不修改任何外部狀態。 >在JavaScript中使用純函數的好處是什麼?它們使您的代碼更具可預測性,更易於測試和調試,因為您只需要考慮功能的輸入和輸出即可。它們還使您的代碼更具可讀性和可維護性,因為它們促進了清晰,簡單的編程風格。此外,純函數高度可重複使用且可組合,使您可以使用更少的代碼來構建更複雜的功能。
>
>在JavaScript中使用純函數的挑戰是什麼? ,他們還提出了一些挑戰。主要挑戰之一是JavaScript不是純粹的功能性語言,它允許副作用和可變數據。這意味著您需要謹慎避免在功能中無意中引入副作用。此外,使用純函數有時會導致更多的詳細代碼,因為您需要避免突變數據並返回新數據。>
>功能編程與並發和並行性如何相關?特別適合併發和並行性。由於純函數沒有副作用,因此可以並行安全地執行它們,而不必擔心種族條件或數據損壞。這使功能編程成為開發並發和並行應用程序的強大工具,尤其是在多核和分佈式計算環境中。函數編程中的功能組成是什麼?
功能組成是功能編程中的基本概念。它涉及組合兩個或多個函數以創建一個新功能。一個函數的結果用作下一個函數的輸入。這使您可以通過簡單函數構建複雜的功能,促進代碼可重複性和可讀性。
>功能編程中的不變性是什麼?
不變性是功能編程的關鍵原理。這意味著一旦創建了數據結構,就無法更改。相反,如果要修改數據結構,則創建一個具有所需更改的新數據結構。這避免了副作用,並使您的代碼更安全,更易於推理。
>>功能編程如何處理狀態?
在功能編程中,仔細處理狀態以避免副作用。功能編程沒有改變狀態,而是使用返回新狀態的純函數。這使國家可預測且易於管理。一些功能性編程語言還為州管理提供了高級功能,例如Haskell中的Monad。 。在並發和並行性很重要的情況下,例如在多核和分佈式計算中,它特別有用。功能編程也通常用於數據處理和分析中,純粹的功能和不變性可以幫助確保數據完整性。此外,在前端開發中越來越多地採用了功能編程概念,諸如react.js之類的流行框架使用功能風格進行組件開發。
以上是合理純粹的功能編程簡介的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。
