摘要:函數式編程是一種以函數為基礎的編程方式和代碼組織方式,從程序員的思路上來說,就是將程序拆分并抽象成多個函數,再組裝回去。在這門語言中,函數是一等公民,函數可以作為函數的參數,函數也可以返回一個函數,因此適合函數式編程風格。
函數式編程 ( Functional Programming ) 是一種以函數為基礎的編程方式和代碼組織方式,從程序員的思路上來說,就是將程序拆分并抽象成多個函數,再組裝回去。
在JavaScript這門語言中,函數是一等公民,函數可以作為函數的參數,函數也可以返回一個函數,因此適合函數式編程風格。
函數式風格的編程,長于數據的處理,且所謂“處理”并不改變數據本身。JavaScript中,數據總是以對象的形式出現,也就是說,函數式的編程對于“接收對象A→處理→處理→處理→得出新對象B”這樣的流程可以很優雅地實現,且不影響對象A本身。
對于JavaScript程序員(無論是前端還是后端),最常見且實用的編程模式當然是抽象出類(以構造函數的形式)并實例化,然后在實例上調用方法。函數式風格的編程不是為了取代這種編程模式,而是為了與之形成互補。
一些特點:
不改變輸入的數據
不耦合,也就是說,函數盡量不影響甚至知曉外部的狀態
保持數據組織形式的簡單,例如,盡量使用JavaScript原生的數據結構(對象、數組等)
函數在函數式編程中,任何代碼可以都是函數,且要求具有返回值,如下示例
</>復制代碼
// 非函數式
var title = "Functional Programming";
var saying = "This is not";
console.log(saying + title); // => This is not Functional Programming
// 函數式
var say = title => "This is " + title;
var text = say("Functional Programming"); // => This is Functional Programming
純函數
純函數在這里指函數內外間是“無”關聯的。主要有下面兩點
沒有副作用(side effect)
不會涉及到外部變量的使用或修改
引用透明
函數內只會依賴傳入參數,在任何時候對函數輸入相同的參數時,總能輸出相同的結果
</>復制代碼
// 非純函數(函數內依賴函數外的變量值)
var title = "Functional Programming";
var say = ()=> "This is not" + title; // <= 依賴了全局變量 title
// 純函數
var say = (title)=>"This is " + title; // <= 依賴了以參數 title 傳入
say("Functional Programming");
不可變數據(immutable)
這里主要是指變量值的不可變。當需要基于原變量值改變時,可通過產生新的變量來確保原變量的不變性,如下
</>復制代碼
// 可變數據
var arr = ["Functional", "Programming"];
arr[0] = "Other"; // <= 修改了arr[0]的值
console.log(arr) // => ["Other", "Programming"] // 變量arr值已經被修改
// 不可變數據
var arr = ["Functional", "Programming"];
// 得到新的變量,不修改了原來的值
var newArr = arr.map(item => {
if(item === "Functional"){
return "Other";
} else {
return item;
}
})
console.log(arr); // => ["Functional", "Programming"] 變量arr值不變
console.log(newArr); // => ["Other", "Programming"] 產生新的變量newArr
之所以使用這種不變值,除了更好的函數式編程外,還能夠維持線程安全可靠,實際上也能讓代碼更加清晰。
設想,如果你定義了一個變量A,A在其他地方被其他人修改了,這樣是不方便定位A的當前值的。
使用 map, reduce 等數據處理函數
強大的 JavaScript 有著越來越多的高能處理數據函數,其中包含了 map、 reduce、 filter 等。
map 能夠對原數組中的值進行逐個處理并產生新的數組,一個簡單例子
</>復制代碼
// map
var data = [1, 2, 3];
var squares = data.map( (item, index, array) => item * item );
console.log(squares); // => [1, 4, 9]
console.log(data);// => [1, 2, 3] data 還是那個 data
reduce 能夠對原數組中的各個值進行結合處理,來產生新的值,如下面例子中,previous 代表上一個值,current 代表當前值,reduce 函數可以傳入第二個參數作為 previous 初始值,不傳時則 previous 初始值為數組中第一個值。
</>復制代碼
// reduce
var sum = [1, 2, 3].reduce( (previous, current, index, array) => previous + current );
console.log(sum); // => 6
函數柯里化 Currying
柯里化 是將多參函數轉換成一系列的單參函數。結合下面例子來說明下
</>復制代碼
// 一個多參函數
var add = (a, b) => a + b;
add(1, 2); // => 3
將上面的多參函數進行柯里化,如下
</>復制代碼
// 柯里化函數
var add = a => b => a + b;
上面柯里化后的函數調用方式也有所轉變,第一次傳入一個參數返回了一個函數,再傳入參數則完成整體的調用,這也是利用的閉包的特性
</>復制代碼
var add1 = add(1);
add1(2); // => 3
柯里化后的函數,也可以應用在生產 “ 函數 ” 上,如下示例
</>復制代碼
var say = title => type => title + " is " + type;
var sayFP = say("Functional Programming");
var sayOther = say("Other Programming");
sayFP("good"); // => Functional Programming is good
sayOther("good"); // => Other Programming is good
組合函數 compose
顧名思義,組合函數是將多個函數進行組合成一個函數。舉個例子
</>復制代碼
var compose = (fn1, fn2) => (arg) => fn1(fn2(arg));
var a = arg => arg + "a";
var b = arg => arg + "b";
var c = compose(a, b); // 將a,b函數進行組合
c("c"); // => cba
上面示例中,當調用組合函數 c 時,傳入的參數會經過 b 函數,接著將 b 函數的返回值作為 a 函數的參數值,從而輸出最終結果。
組合函數 c 就像管道一樣,將水流( 返回值 )流經各個函數中進行處理。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87930.html
摘要:前言繼續向下看廖大教程,看到了函數式編程這一節,當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 前言 繼續向下看廖大教程,看到了函數式編程這一節,當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 函數式編程 上學期有上一門叫 人工智能 的課,老師強行要我們學了一個叫做 prolog 的語言,哇那感覺確實難受,思維方式完全和之前學過的不一樣,...
摘要:以我自己的理解,函數式編程就是以函數為中心,將大段過程拆成一個個函數,組合嵌套使用。越來越多的跡象表明,函數式編程已經不再是學術界的最愛,開始大踏步地在業界投入實用。也許繼面向對象編程之后,函數式編程會成為下一個編程的主流范式。 使用React也滿一年了,從剛剛會使用到逐漸探究其底層實現,以便學習幾招奇技淫巧從而在自己的代碼中使用,寫出高效的代碼。下面整理一些知識點,算是React看書...
摘要:是一門最近比較流行的靜態類型編程語言,而且和一樣同屬系。這個生成的構造函數是合成的,因此不能從或中直接調用,但可以使用反射調用。 showImg(https://segmentfault.com/img/remote/1460000012958496); Kotlin是一門最近比較流行的靜態類型編程語言,而且和Groovy、Scala一樣同屬Java系。Kotlin具有的很多靜態語言...
摘要:在學習的過程中時常會聽到一個名次函數式編程,那么究竟什么是函數式編程,函數式編程又有什么優點,這就在這篇博客進行一個簡單的總結吧主要內容函數式編程的概念函數式編程的優點與示例什么是函數式編程首先,我們放下編程的概念,我們來看函數。 在學習 JS 的過程中時常會聽到一個名次——函數式編程,那么究竟什么是函數式編程,函數式編程又有什么優點,這就在這篇博客進行一個簡單的總結吧~ 主要內容: 函...
閱讀 3542·2021-09-10 10:51
閱讀 2517·2021-09-07 10:26
閱讀 2493·2021-09-03 10:41
閱讀 818·2019-08-30 15:56
閱讀 2907·2019-08-30 14:16
閱讀 3494·2019-08-30 13:53
閱讀 2112·2019-08-26 13:48
閱讀 1923·2019-08-26 13:37