純函數這個這個詞我相信小夥伴們多多少少都據說過,它是函數式編程的基礎。本文主要是對純函數進行探討,包括基本概念,優勢,運用的經典案例以及咱們平常該如何去合理的使用等等。javascript
首先咱們來看看純函數的基本概念:html
相同的輸入,老是會的到相同的輸出,而且在執行過程當中沒有任何反作用。
該怎麼去理解上面的概念呢?咱們要把上面這句話拆成兩部分來看。java
相同的輸入,老是會獲得相同的輸出。react
來看看下面的例子:編程
let a = 1; function xAdd(x) { return x + a; }; xAdd(1); //2
上面這個函數就不是一個純函數,由於在咱們程序執行的過程當中,變量a
極可能會發生改變,當變量a發生改變時,咱們一樣執行xAdd(1)
時獲得的輸出也就不一樣了。redux
再看另外一個例子:segmentfault
function sum(x, y) { return x + y; }; sum(1,2); //3
在這個例子中,符合相同的輸入獲得相同的輸出這個概念,sum
是一個純函數。數組
執行過程當中沒有任何反作用。緩存
這裏咱們要搞清楚什麼是反作用,這裏的反作用指的是函數在執行過程當中產生了外部可觀察變化。dom
上面一系列操做均可以被稱爲是反作用。下面能夠接着看一個修改外部數據從而產生反作用的例子:
let a = 1; function func() { a = 'b'; }; func(); console.log(a); // b
咱們運行了func
函數,外部的變量a
的值發生了改變,這就是產生了所謂的反作用,因此func
不是一個純函數。當咱們這樣進行修改:
function func2() { let a = 1; a = 'a'; return a }; func(); // a
函數fun2
不會對產生外部可觀察變化,也就不會產生反作用,它就是一個純函數。
一個純函數,上面所說的兩個條件缺一不可。
經過了解純函數的概念,我相信有的小夥伴已經能感受到純函數的一些的好處了:
既然純函數有這麼多好處,那麼咱們來看看有哪些運用純函數的經典案例。
數組的不少基本方法都是純函數,例如map
,forEach
,filter
,reduce
等等。
Redux中三大原則之一使用純函數來執行修改,其中就運用了Reducer來描述 action 如何改變 state tree。
Reducer 只是一些純函數,它接收先前的 state 和 action,並返回新的 state。 --Redux
中文文檔
Lodash 是一個一致性、模塊化、高性能的 JavaScript 實用工具庫。我相信不少小夥伴也常常用到吧,這也是純函數表明。
固然還有不少,這裏就不一一舉例了,總的來講,純函數仍是十分常見的。
在實際開發中,咱們能夠合理的去運用純函數來提升咱們的開發效率和代碼質量。
咱們可使用純函數的的方式來建立組件:
function Header(props) { return <h2>{props.text}</h2> }
對比一下使用Class(類)組件的方式建立組件:
class Header extends React.Component { render() { return <h1>{this.props.text}</h1> } }
咱們能夠總結出純函數組件的一些優勢:
固然純函數組件也有本身的缺點,例如:沒有生命週期。
生命週期有時候並不可少,所幸如今咱們也已經有了很好的解決方案——react-hooks。利用hooks函數,咱們能夠在函數組件中使用等價於生命週期,狀態管理等方法。
在編寫公共方法的時候,咱們儘可能用純函數來進行編寫。
假設咱們要編寫一個把數組中的小寫字母轉爲大寫字母的公共方法:
let lists = ["q","w","e"]; let upperCaseLists = () => { let arr = []; for (let i=0, length= lists.length; i<length; i++) { let item = lists[i]; arr.push(item.toUpperCase()); } lists = arr; }
上面這個函數雖然能夠實現邏輯複用,可是有反作用,確定是不適合用來作公共方法的,因此咱們要優化它:
let upperCaseLists = (value) => { let arr = []; for (let i=0, length= value.length; i<length; i++) { let item = value[i]; arr.push(item.toUpperCase()); } return arr; }
使用可讀性更好的forEach
來優化:
let upperCaseLists = (value) => { let arr = []; value.forEach((item) => { arr.push(item.toUpperCase()); }) return arr; }
繼續用map進一步優化:
let upperCaseLists = (value) => { return value.map((item) => item.toUpperCase()) }
是否是很簡潔?具體方法怎麼優化要根據實際狀況和業務需求來。
https://segmentfault.com/a/11...
https://cuggz.blog.csdn.net/a...
純函數這個概念其實並不複雜,在沒有深刻了解以前咱們工做中也必定遇到過,也在不經意間用過。只有要合理的去運用它,就是開發中的一把利器。