电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:261日期: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
      主站蜘蛛池模板: 爱德华真空泵油/罗茨泵维修,爱发科-比其尔产品供应东莞/杭州/上海等全国各地 | 广州展台特装搭建商|特装展位设计搭建|展会特装搭建|特装展台制作设计|展览特装公司 | 洛阳防爆合格证办理-洛阳防爆认证机构-洛阳申请国家防爆合格证-洛阳本安防爆认证代办-洛阳沪南抚防爆电气技术服务有限公司 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 净化板-洁净板-净化板价格-净化板生产厂家-山东鸿星新材料科技股份有限公司 | 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 - 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 | 开云(中国)Kaiyun·官方网站 - 登录入口 | 走心机厂家,数控走心机-台州博城智能科技有限公司 | 超声波破碎仪-均质乳化机(供应杭州,上海,北京,广州,深圳,成都等地)-上海沪析实业有限公司 | 注浆压力变送器-高温熔体传感器-矿用压力传感器|ZHYQ朝辉 | 据信,上课带着跳 D 体验-别样的课堂刺激感受引发网友热议 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 江苏齐宝进出口贸易有限公司| 北京中创汇安科贸有限公司| 英语词典_成语词典_日语词典_法语词典_在线词典网 | STRO|DTRO-STRO反渗透膜(科普)_碟滤| 啤酒设备-小型啤酒设备-啤酒厂设备-济南中酿机械设备有限公司 | 称重传感器,测力传感器,拉压力传感器,压力变送器,扭矩传感器,南京凯基特电气有限公司 | hdpe土工膜-防渗膜-复合土工膜-长丝土工布价格-厂家直销「恒阳新材料」-山东恒阳新材料有限公司 ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | AGV无人叉车_激光叉车AGV_仓储AGV小车_AGV无人搬运车-南昌IKV机器人有限公司[官网] | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 滚筒烘干机_转筒烘干机_滚筒干燥机_转筒干燥机_回转烘干机_回转干燥机-设备生产厂家 | 广州迈驰新GMP兽药包装机首页_药品包装机_中药散剂包装机 | 泰安塞纳春天装饰公司【网站】| 彩信群发_群发彩信软件_视频短信营销平台-达信通 | 东莞ERP软件_广州云ERP_中山ERP_台湾工厂erp系统-广东顺景软件科技有限公司 | 数控走心机-走心机价格-双主轴走心机-宝宇百科| 有源电力滤波装置-电力有源滤波器-低压穿排电流互感器|安科瑞 | 电池高低温试验箱-气态冲击箱-双层电池防爆箱|简户百科 | 附着力促进剂-尼龙处理剂-PP处理剂-金属附着力处理剂-东莞市炅盛塑胶科技有限公司 | 陕西视频监控,智能安防监控,安防系统-西安鑫安5A安防工程公司 | 三价铬_环保铬_环保电镀_东莞共盈新材料贸易有限公司 | 深圳高新投三江工业消防解决方案提供厂家_服务商_园区智慧消防_储能消防解决方案服务商_高新投三江 | 洛阳装修公司-洛阳整装一站式品牌-福尚云宅装饰 | 学叉车培训|叉车证报名|叉车查询|叉车证怎么考-工程机械培训网 | 破碎机_上海破碎机_破碎机设备_破碎机厂家-上海山卓重工机械有限公司 | 模具硅橡胶,人体硅胶,移印硅胶浆厂家-宏图硅胶科技 | 蓝牙音频分析仪-多功能-四通道-八通道音频分析仪-东莞市奥普新音频技术有限公司 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 | 蔬菜配送公司|蔬菜配送中心|食材配送|饭堂配送|食堂配送-首宏公司 | 废气处理_废气处理设备_工业废气处理_江苏龙泰环保设备制造有限公司 |