鑰匙要點
- 純函數在功能編程中至關重要,因為它們返回相同輸入的相同輸出而不會引起副作用,增強可預測性和可檢驗性。 通過將過程分解為更簡單,不可變的函數, 功能編程可降低程序的複雜性,從而有助於最大程度地減少錯誤並改善代碼可讀性。
- > 在功能編程中 過度反應,同時降低代碼複雜性,可能會導致難以理解和維護的代碼,從而突出餘額的重要性。
- > >基本的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>或,這種替代的API使用諸如提取和承諾之類的抽象來有助於我們進一步闡明我們的異步行動的含義。
>
<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 alt="合理純粹的功能編程簡介" >', { 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>能夠簡單地測試我們的程序是純粹功能的關鍵好處,因此在本節中,我們將為我們較早查看的Flickr模塊設置測試安全帶。
>
>啟動終端,並準備好您的文本編輯器,我們將使用摩卡咖啡作為測試跑步者,而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 alt="合理純粹的功能編程簡介" >', { 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 alt="合理純粹的功能編程簡介" >', { 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 alt="合理純粹的功能編程簡介" >', { src: url })) </span> <span>return images </span><span>} </span>>注意:如果您希望Mocha觀察更改並自動運行測試,則還可以在此命令的末尾添加一個-w標誌,它們將在重新運行時運行得更快。
>
<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 alt="合理純粹的功能編程簡介" >', { src: url })) </span><span>} </span><span>let responseToImages = _.compose(images, urls) </span>測試我們的flickr模塊
讓我們將模塊添加到lib/flickr.js
<span>let responseToImages = (data)=> { </span> <span>return images(urls(data)) </span><span>} </span>我們的模塊正在公開兩種方法:flickr將被公開消費和私人功能_responSetoimages,以便我們可以孤立地測試。
>
>我們有幾個新的依賴性: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>>我們的測試可以坐在測試/flickr.js中,我們將對預定義輸入的功能發出輸出發出斷言。 我們“存根”或覆蓋全局獲取方法以攔截和偽造HTTP請求,以便我們可以直接擊中Flickr API進行測試。
>
<span>// pure </span><span>var checkAge = function(age) { </span> <span>var minimum = 21; </span> <span>return age >= minimum; </span><span>}; </span>>通過NPM測試再次運行我們的測試,您應該看到三個保證綠色tick。
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中文網其他相關文章!

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

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

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),