日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JavaScript數據類型對函數式編程的影響示例解析

瀏覽:380日期:2022-06-01 14:41:08
目錄
  • 前言
  • JavaScript中 的數據類型中的可變數據
    • 原始類型(基本類型)
    • 對象類型(引用類型)
  • JavaScript 為何能會讓純函數變得不純?
    • 如何解決可變數據的影響?
      • 數據拷貝
      • 使用不可變數據方案
    • 總結

      前言

      本篇文章是JavaScript 函數式編程 學習系列第二篇,感興趣也可以先去看第一篇:

      • 一文理解JavaScript中的函數式編程的概念
      • JavaScript數據類型對函數式編程的影響
      • 不可變數據方案之immer.js實現探索

      前文 一文理解JavaScript中的函數式編程的概念 中寫了函數式編程的概念,本篇文章繼上文之后,來梳理 JavaScript 數據類型對函數式編程的影響。

      函數式編程編程的核心就是 純函數 和隔離 副作用 ,為了讓 純函數 保持純粹,純函數的參數或者內部引用的外部數據應該是不可變數據。但 JavaScript 中的數據類型并不是都是不可變的,而數據類型的可變性,很有可能讓 純函數 變的不純。

      因此,本篇文章的目的有兩點:

      • 探索 JavaScript 的數據類型來了解的可變數據的根源。
      • JavaScript 的可變數據數據是怎么讓 純函數 變得不純的?
      • 如何解決 可變數據 的影響?

      JavaScript中 的數據類型中的可變數據

      在 JavaScript 中,數據類型有以下 8 種:

      • null
      • undefined
      • boolean
      • number
      • symbol -- 在 es6 中被加入
      • bigint -- es6+ 被加入
      • object

      注意點:

      在 JavaScript 中,變量是沒有類型的,值才有類型。變量可以在任何時候,持有任何值。

      原始類型(基本類型)

      上面 8 中類型除了 object ,其他都是原始類型,原始類型存儲的都是值,其特點有兩點:

      • 沒有方法可以直接調用
      • 原始類型的數據是不可被改變的,改變一個變量的值,并不是把值改變了,而是讓變量擁有新的值。

      注意點:

      • '1'.toString()或者false.toString()等可以用的原因是被強制轉換成了 String 類型也就是對象類型,所以可以調用 toString 函數。
      • 對于null來說,很多人會認為它是個對象類型,其實是錯誤的。typeof null 會輸出 object,這只是 JS 存在的一個悠久 Bug,而且好像永遠不會也不會被修復,因為有太多已經存在的 web 的內容依存著這個 bug。注: 在 JS 的最初版本中使用的是 32 位系統,為了性能考慮使用低位存儲變量的類型信息,000開頭代表是對象,然而 null 表示為全零,所以將它錯誤的判斷為 object 。雖然現在的內部類型判斷代碼已經改變了,但是對于這個 Bug 卻是一直流傳下來。

      對象類型(引用類型)

      而除了原始類型,剩下的 object 就是對象類型,和原始類型的不同點在于:原始類型存儲的是值,對象類型存儲的是地址。

      經典示例:

      var c = 1;
      var d = c;
      d = 2;
      console.log(c === d) // false
      var a = {
          name: "張三",
          age: 20
      }
      var b = a;
      b.age = 21;
      console.log(a.age === b.age) // true
      

      示例中把變量 a 的值給到了變量 b , b 修改了age 屬性,但是 a 的 age 屬性也跟著變了,是因為 var b = a 是 a 把對象的引用地址賦值給 b ,這時候 a 和 b 指向的是內存中的同一個數據。

      而 c 給 d 的是值,并不是一個引用,相當于復制了一份數據。

      因此可以知道原型類型的數據是不可變的,而對象類型的數據是可變的。

      JavaScript 為何能會讓純函數變得不純?

      JavaScript 中的對象類型的數據是可變,而可變性,就代表了不確定性,純函數 中使用了不確性的數據就會導致不純,因為其違背了 純函數 的特征:不受外界影響,不影響外界。

      下面來看一個例子:

      A 同學寫了這么一段代碼,初始化生成了一個 “zhangsan” 用戶。

      export const defaultUserInfo = {
          name: "名稱",
          age: 20,
          hobby: ["玩耍"]
      };
      export function initUser(userTemplate, name, age) {
          const newUser = userTemplate;
          newUser.name = name;
          newUser.age = age;
          return newUser;
      }
      const zhangsan = userInit(userDefaultInfo, "zhangsan", 21);
      

      然后 B 同學在開發其他頁面的時候,看到有初始化用戶信息的方法,然后直接復制過去,初始化了一個 “lisi” 用戶。

      import { defaultUserInfo, initUser } from "xxx模塊"。
      const lisi = userInit(userDefaultInfo, "lisi", 21);
      

      檢測的時候看到自己初始化的用戶信息正確的就沒有去檢查之前 A 同學的是否是正確的,上線后發現所有的用戶都變成了 lisi 。因為 userDefaultInfo 是一個引用類型,userInit(userDefaultInfo, "xxx", xx) 操作的都是內存中的同一個對象。其原因就是因為 A 和 B 開發者犯了一個錯誤,把可變數據傳遞到了 userInit 函數內部進行處理,哪怕進行了淺層拷貝,也出現了問題。究其原因還是因為給函數傳遞進去了一個 可變數據。

      我們校驗一個 純函數 有效性的關鍵依據,永遠是“針對已知的輸入,能否給出符合預期的輸出”,而上面例子中 initUser 函數沒有違背這個規則,但是在可變數據的影響下,讓它產生了 副作用,對外界已有的數據造成了影響。

      如何解決可變數據的影響?

      數據拷貝

      從使用函數方的角度來看,既然造成這個問題的原因是因為傳遞進去的數據是 可變數據 ,那么我就復制一份數據傳遞給函數內部使用,隨便你怎么修改,都不會影響外界其他數據。

      比如我們使用前面例子中的 initUser 函數時,先拷貝一份數據:

      function copyFunc(object) {
          return JSON.parse(JSON.string(object));
      }
      const zhangsan = userInit(copyFunc(userDefaultInfo), "zhangsan", 21);
      const lisi = userInit(copyFunc(userDefaultInfo), "lisi", 21);
      console.log(zhangsan.name === lisi.name); // false
      

      進行拷貝后的數據傳遞給 userInit 函數,就不會出現問題了。這里的 copyFunc 只能針對部分數據類型,對不少類型是不支持的,具體可以去看一下 關于JSON.parse(JSON.stringify(obj))實現深拷貝應該注意的坑 這篇文章。

      從被調用函數方來看,在使用 object 類型數據時,函數內部盡量不要去修改外界 object 數據(通過參數傳遞,或者直接使用外界的對象都不建議去修改),修改之前可以拷貝一份再修改。

      比如:

      export function initUser(userTemplate, name, age) {
          const newUser = copyFunc(userTemplate);
          newUser.name = name;
          newUser.age = age;
          return newUser;
      }
      

      使用不可變數據方案

      拷貝的數據比較大的時候,會出現性能問題,因此出現了不可變數據的方案。

      現在不可變數據常見的有兩種: Immutable.js 和 immer.js 。它們都能實現在操作數據后,返回新的一個數據,而不影響之前的數據。

      Immutable.js 實現了持久化數據結構,實現原理說明(引用于immutable.js 和 immer):

      • 使用舊數據創建新數據時,要保證舊數據同時可用且不變。同時為了避免 deepCopy 把所有節點都復制一遍帶來的性能問題,immutable 使用了結構共享方式,即如果對象樹中的一個節點改變,只修改這個節點和受它影響的父節點,其他節點共享。
      • immutable-js 使用了另一套數據結構 api,它會將原生數據類型都轉化為 immutable-js 內部對象。

      因此 Immutable.js 需要嚴格使用它自定義的操作數據的方法才行。

      immer.js 利用了 es6 的 Proxy 來進行對數據操作的攔截實現,具體原理可去 剖析 Immer.js 工作原理與設計模式 這里看看,也可以去網上查詢。

      總結

      • 分析 JavaScript中 的數據類型中的可變數據根源:Object 數據結構。
      • 探索了其可變數據數據是怎么對 純函數 造成的影響:Object 數據的不確定性。
      • 分析了如何解決 可變數據 的影響:深拷貝 和使用 不可變數據結構.

      參考:

      • JavaScript 函數式編程實踐指南
      • immutable.js 和 immer)

      以上就是JavaScript數據類型對函數式編程的影響示例解析的詳細內容,更多關于JavaScript數據類型函數式編程的資料請關注其它相關文章!

      標簽: JavaScript
      日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
      欧美日韩一区二区综合| 日韩精品免费一区二区夜夜嗨| 日韩1区2区日韩1区2区| 蜜臀av性久久久久蜜臀aⅴ流畅 | 日本色综合中文字幕| 亚洲午夜久久| 在线精品观看| 亚洲欧美网站在线观看| 久久99伊人| 丝袜国产日韩另类美女| 香蕉成人久久| 综合干狼人综合首页| 亚洲三级av| 91久久精品无嫩草影院| 国产精品nxnn| 麻豆91精品91久久久的内涵| 欧美激情91| 精品国产不卡| 日本综合字幕| 亚洲综合三区| 青青伊人久久| 精品久久在线| 亚洲性色视频| 伊人www22综合色| 日韩高清欧美激情| 精品久久91| 亚洲午夜av| 日本亚洲视频| 久久久久伊人| 国产精品97| 久久最新视频| 欧美日韩午夜| a国产在线视频| 欧美日韩国产亚洲一区| 蜜桃免费网站一区二区三区| 国产亚洲久久| 香蕉视频亚洲一级| 视频一区二区不卡| 麻豆精品av| 久久精品欧美一区| 成人在线超碰| 99国产精品久久久久久久 | 国产精品一区二区三区美女 | 国产剧情在线观看一区| www.51av欧美视频| 在线午夜精品| 国产精品**亚洲精品| 日韩在线第七页| 免费人成在线不卡| 动漫av一区| 一区二区电影| 欧美日韩国产观看视频| 亚洲精品三级| 久久久久久自在自线| 免费黄网站欧美| 精品久久99| 日韩午夜av| 国产精品nxnn| 亚洲经典在线| 麻豆极品一区二区三区| 婷婷综合在线| 国产精品v日韩精品v欧美精品网站 | 久久亚洲欧洲| 久久超碰99| 99精品小视频| 国产精品亚洲四区在线观看| 欧美色图国产精品| 国产精品久久久久久模特| 久久亚洲成人| 老牛国内精品亚洲成av人片| 99成人在线| 欧美xxxx中国| 日韩精品一区二区三区中文在线| 久久电影tv| 欧美亚洲三区| 国产精品丝袜xxxxxxx| 国产成人调教视频在线观看| 视频精品一区二区| 日韩一区二区三区免费播放| 天堂俺去俺来也www久久婷婷| 日韩欧美一区二区三区免费观看| 日韩精品一区二区三区免费视频| 激情欧美一区二区三区| 九九久久国产| 91精品国产自产精品男人的天堂| 欧美在线亚洲| 日韩欧美视频专区| 久久香蕉精品香蕉| 日韩超碰人人爽人人做人人添| 亚洲精品一区二区妖精| 超碰在线99| 欧美日韩网址| 中文字幕视频精品一区二区三区 | 日韩综合精品| 国产精品毛片视频| 日韩高清二区| 一区二区三区国产在线| 欧美日韩国产一区二区三区不卡| 成人在线超碰| 国产精品sm| 欧美天堂一区二区| 亚洲免费福利一区| 亚洲一级在线| 久久国产影院| 美女av在线免费看| 精品国产日韩欧美精品国产欧美日韩一区二区三区| 中文字幕免费精品| 国产综合视频| 欧美不卡高清一区二区三区| 麻豆久久一区二区| 国产区精品区| 国产亚洲观看| 国产视频一区二| 青青草精品视频| 日韩精品高清不卡| 蜜臀va亚洲va欧美va天堂| 99国产成+人+综合+亚洲欧美| 国产精品av一区二区| 欧美日韩精品一区二区视频| 久久婷婷亚洲| 久久中文视频| 免费不卡中文字幕在线| 日本久久成人网| 日韩精品91| 999国产精品视频| 亚洲精品国产嫩草在线观看| 日韩成人精品一区| 日韩在线不卡| 亚洲高清成人| 国产亚洲高清视频| 久久国产精品久久久久久电车| 日韩一区二区免费看| 亚洲欧美视频| 亚洲乱码一区| 国产欧美日韩| 亚洲免费网址| 999在线观看精品免费不卡网站| 亚洲欧美日韩高清在线| 国产精品外国| 午夜电影一区| 日韩av午夜在线观看| 国产精品高潮呻吟久久久久| 精品理论电影在线| 免费在线小视频| 亚洲电影在线一区二区三区| 久久不射网站| 18国产精品| 国产一区二区三区亚洲| 久久精品国产亚洲夜色av网站| 欧美另类专区| 五月亚洲婷婷 | 国产欧美日韩在线一区二区| 国产精品一区二区三区四区在线观看| 久久亚洲国产精品尤物| 高清不卡亚洲| 欧美特黄一区| 日韩黄色在线观看| 久久精品女人| 九九久久电影| 免费国产亚洲视频| 久久精品999| 麻豆视频在线观看免费网站黄| 欧美午夜精彩| 亚洲a成人v| 国产精品欧美三级在线观看 | 国产无遮挡裸体免费久久| 国产成人免费av一区二区午夜| 欧美午夜精品一区二区三区电影| 爽好久久久欧美精品| 国产日韩免费| 成人久久一区| 亚洲免费中文| 欧美国产精品| 欧美中文字幕一区二区| 婷婷精品在线| 久久香蕉精品香蕉| 亚洲激情黄色| 免费在线播放第一区高清av| 国产99亚洲| 国产日韩高清一区二区三区在线| av中文资源在线资源免费观看| 久久www成人_看片免费不卡| 久久wwww| 国产二区精品| 国产精品片aa在线观看| 国产精品99免费看| 日本不卡一二三区黄网| 水蜜桃久久夜色精品一区| 免费久久精品视频| 成人亚洲一区| 婷婷视频一区二区三区| 日韩大片免费观看| 亚洲久草在线| 肉色欧美久久久久久久免费看 | 亚洲综合日本| 日产精品一区二区| 日韩精品免费视频一区二区三区| 日韩在线高清| 欧美日本一区| 午夜精品一区二区三区国产|