<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          純函數(shù)是什么?怎么合理運用純函數(shù)?

          共 3085字,需瀏覽 7分鐘

           ·

          2021-04-12 14:30

          作者:xmanlin

          來源:Segmentfault 思否社區(qū)




          前言

          純函數(shù)這個這個詞我相信小伙伴們多多少少都聽說過,它是函數(shù)式編程的基礎(chǔ)。本文主要是對純函數(shù)進(jìn)行探討,包括基本概念,優(yōu)點,運用的經(jīng)典案例以及我們?nèi)粘T撊绾稳ズ侠淼氖褂玫鹊取?/span>

          純函數(shù)的概念

          首先我們來看看純函數(shù)的基本概念:

          相同的輸入,總是會的到相同的輸出,并且在執(zhí)行過程中沒有任何副作用。

          該怎么去理解上面的概念呢?我們要把上面這句話拆成兩部分來看。

          相同的輸入,總是會得到相同的輸出。

          來看看下面的例子:

          let a = 1;

          function xAdd(x) {
          return x + a;
          };
          xAdd(1); //2

          上面這個函數(shù)就不是一個純函數(shù),因為在我們程序執(zhí)行的過程中,變量a很可能會發(fā)生改變,當(dāng)變量a發(fā)生改變時,我們同樣執(zhí)行xAdd(1)時得到的輸出也就不同了。

          再看另一個例子:

          function sum(x, y) {
          return x + y;
          };
          sum(1,2); //3

          在這個例子中,符合相同的輸入得到相同的輸出這個概念,sum是一個純函數(shù)。

          執(zhí)行過程中沒有任何副作用。

          這里我們要搞清楚什么是副作用,這里的副作用指的是函數(shù)在執(zhí)行過程中產(chǎn)生了外部可觀察變化。

          1. 發(fā)起HTTP請求
          2. 操作DOM
          3. 修改外部數(shù)據(jù)
          4. console.log()打印數(shù)據(jù)
          5. 調(diào)用Date.now()或者M(jìn)ath.random()

          上面一系列操作都可以被稱為是副作用。下面可以接著看一個修改外部數(shù)據(jù)從而產(chǎn)生副作用的例子:

          let a = 1;
          function func() {
          a = 'b';
          };
          func();
          console.log(a); // b

          我們運行了func函數(shù),外部的變量a的值發(fā)生了改變,這就是產(chǎn)生了所謂的副作用,所以func不是一個純函數(shù)。當(dāng)我們這樣進(jìn)行修改:

          function func2() {
          let a = 1;
          a = 'a';
          return a
          };
          func(); // a

          函數(shù)fun2不會對產(chǎn)生外部可觀察變化,也就不會產(chǎn)生副作用,它就是一個純函數(shù)。

          一個純函數(shù),上面所說的兩個條件缺一不可。

          純函數(shù)的好處

          通過了解純函數(shù)的概念,我相信有的小伙伴已經(jīng)能感覺到純函數(shù)的一些的好處了:

          • 更容易進(jìn)行測試,結(jié)果只依賴輸入,測試時可以確保輸出穩(wěn)定
          • 更容易維護(hù)和重構(gòu),我們可以寫出質(zhì)量更高的代碼
          • 更容易調(diào)用,我們不用擔(dān)心函數(shù)會有什么副作用
          • 結(jié)果可以緩存,因為相同的輸入總是會得到相同的輸出

          純函數(shù)運用的經(jīng)典案例

          既然純函數(shù)有這么多好處,那么我們來看看有哪些運用純函數(shù)的經(jīng)典案例。

          數(shù)組的基本方法

          數(shù)組的很多基本方法都是純函數(shù),例如map,forEach,filter,reduce等等。

          redux中的reducer

          Redux中三大原則之一使用純函數(shù)來執(zhí)行修改,其中就運用了Reducer來描述 action 如何改變 state tree。

          Reducer 只是一些純函數(shù),它接收先前的 state 和 action,并返回新的 state。--Redux
          中文文檔

          Lodash

          Lodash 是一個一致性、模塊化、高性能的 JavaScript 實用工具庫。我相信很多小伙伴也經(jīng)常用到吧,這也是純函數(shù)代表。

          當(dāng)然還有很多,這里就不一一舉例了,總的來說,純函數(shù)還是十分常見的。

          我們?nèi)绾魏侠砣ナ褂?/span>

          在實際開發(fā)中,我們可以合理的去運用純函數(shù)來提高我們的開發(fā)效率和代碼質(zhì)量。

          純函數(shù)組件

          我們可以使用純函數(shù)的的方式來創(chuàng)建組件:

          function Header(props) {
          return <h2>{props.text}</h2>
          }

          對比一下使用Class(類)組件的方式創(chuàng)建組件:

          class Header extends React.Component {
          render() {
          return <h1>{this.props.text}</h1>
          }
          }

          我們可以總結(jié)出純函數(shù)組件的一些優(yōu)點:

          • 無副作用,我們不用擔(dān)心副作用帶來的一些難以捕捉的問題
          • 語法更簡潔,可讀性好,代碼量相對較小,易復(fù)用
          • 占用內(nèi)存小,無生命周期和狀態(tài)管理,提升了性能

          當(dāng)然純函數(shù)組件也有自己的缺點,例如:沒有生命周期。

          生命周期有時候并不可少,所幸現(xiàn)在我們也已經(jīng)有了很好的解決方案——react-hooks。利用hooks函數(shù),我們可以在函數(shù)組件中使用等價于生命周期,狀態(tài)管理等方法。


          合理運用純函數(shù)編寫公共方法

          在編寫公共方法的時候,我們盡量用純函數(shù)來進(jìn)行編寫。

          假設(shè)我們要編寫一個把數(shù)組中的小寫字母轉(zhuǎn)為大寫字母的公共方法:

          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;
          }

          上面這個函數(shù)雖然可以實現(xiàn)邏輯復(fù)用,但是有副作用,肯定是不適合用來做公共方法的,所以我們要優(yōu)化它:

          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來優(yōu)化:

          let upperCaseLists = (value) => {
          let arr = [];
          value.forEach((item) => {
          arr.push(item.toUpperCase());
          })
          return arr;
          }

          繼續(xù)用map進(jìn)一步優(yōu)化:

          let upperCaseLists = (value) => {
          return value.map((item) => item.toUpperCase())
          }

          是不是很簡潔?具體方法怎么優(yōu)化要根據(jù)實際情況和業(yè)務(wù)需求來。

          參考

          https://segmentfault.com/a/1190000007491981

          https://cuggz.blog.csdn.net/article/details/113792471

          https://www.redux.org.cn/

          最后

          純函數(shù)這個概念其實并不復(fù)雜,在沒有深入了解之前我們工作中也一定遇到過,也在不經(jīng)意間用過。只有要合理的去運用它,就是開發(fā)中的一把利器。



          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91在线无码精品秘 入口九色十 | 亚洲免费观看在线观看 | 俺去俺来也在线www色情网 | 一级AA一级精品 | 第一色网站|