immutability因React官方出鏡之使用總結分享!

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,梅斌的專欄,首席填坑官∙蘇南專欄

引言

  以前項目中遇到數據拷貝、引用之間數據層級嵌套過深,拷貝的值相互之間影響的問題,後來引入了immutability-helper,使用過程當中的一些總結,跟你們分享下,至於爲何不是immutable,請看下文分解,這裏是@IT·平頭哥聯盟,我是首席填坑官——蘇南javascript

​  相信你們在面試/工做中都遇到過js對象/數組的拷貝問題,面試官問你,你通常怎麼作??在如今ES6盛行的當下,不會一點ES6都很差意思說本身是前端(其實我通常都說本身是攻城獅、切圖崽😝),咱們想的大多第一想法,以下:html

  • Object.assign - 最方便;
  • [...] - 最有逼格;
  • JSON.parseJSON.stringify - 完美組合;
  • $.extend() - jQuery時代的引領潮流時尚前沿的API;
  • 最後想到的纔是本身遞歸實現一個;

  可是一般咱們使用的Object.assign屬於淺拷貝,當數據嵌套層級較深時,就……呵呵了;而JSON.parse、stringify它應該是建立一個臨時可能很大的字符串,而後又訪問解析器,性能是比較慢的。因而後來發現了 immutable「不可變數據」,曾經我也一度特別喜歡它,但時間久了,慢慢發現,它過於有個性了些、凡事都都沒有任何商量的餘地,全部的數據,從建立、變動、插入、刪除等操做,都要按它的套路來,對於我這種一輩子放蕩不羈愛自由的人來講,長時間的約束,是不能忍的;都說兩人若是三觀不合,是沒法長久下去的,可能也是緣份吧,在後來的某一天偶然的閒逛中邂逅了新歡 ————Immutability Helpers前端

  嗯,今天的主題就是給你們分享一下,Immutability Helpers的一些用法,會介紹API的使用操做和小技巧,若有不理解不對,請糾正:
  java

太興奮了,差點忘了,補充一下,一個簡單的拷貝:
//實現一個簡單的遞歸數據拷貝
  let customClone = (rawObj)=>{
    let copyObj = {};

    for (var key in rawObj) {
      if( typeof rawObj[key] === 'object' && Object.prototype.toString.call(rawObj[key]) !== '[object Array]'){
          copyObj[key] = customClone(rawObj[key]);
      }else{
          copyObj[key] = rawObj[key];
      };
    };
    return copyObj;
  };
  let objA =  {"name":"蘇南","sex":"男","height":"176"};
  let objB =  customClone(objA);
      objB.signature = "寶劍鋒從磨礪出,梅花香自苦寒來,作有溫度的攻城獅";

  console.log(objA);
  console.log(objB);

由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,展現Object.assign拷貝問題

  • 補充一個 Object.assign 的坑 :
let data = {
    a:1,
    b:2,
    children:{
      name:"蘇南",
      organization:"@IT·平頭哥聯盟",
      job:"首席填坑官",
      address:"ShenZhen",
      age:18
    }
  };
  let data2 = Object.assign({},data);
  data2.children.age = 28;
  data2.children.job = "首席甩鍋官";
  data2.b = 666;
  console.log("我是原始數據 data:",data);
  console.log("我是複製後的數據 data2:",data2);

公衆號:honeyBadger8,展現Object.assign拷貝問題

immutable 最後的一次回顧

  都說有了新歡,忘了舊愛,但我不是那種無情無義的人,最後正式介紹一下 immutable,爲我倆的……畫上一個圓滿的句號:react

  再次強調,並非以爲immutable很差,不夠強大,只是本身我的觀點,有些不喜歡而已,各位immutable粉勿噴,想了解更多的同窗能夠點擊這裏git

Immutable data encourages pure functions (data-in, data-out) and lends itself to much simpler application development and enabling techniques from functional programming such as lazy evaluation.
使用示例:
const list1 = List([ 1, 2, 3 ]);
  const list2 = List([ 4, 5, 6 ]);
  const array = [ 7, 8, 9 ];
  const list3 = list1.concat(list2, array);
  console.log(list3) // List {size: 9, _origin: 0, _capacity: 9, _level: 5, _root: null, …} 是不能直接獲取到數據的,須使用get,-- list3.get(0)
let data = fromJS({
    obj:{}
  });
  let data1 = {
    a:1,
    b:2,
    children:{
      name:"蘇南",
    }
  };
  let data2 = data.mergeIn(['obj'],data1,{c:666});
  console.log("獲取的數據:",data2.getIn(['obj','c']));
  console.log("這裏是由formJS建立的數據:",data2.getIn(['obj','children','name']));//

公衆號:honeyBadger8,展現Object.assign拷貝問題

使用immutable後,全部數據都要相似選擇器,一個一個往下選擇,並非說它很差、功能不夠強大,只是本身有些不喜歡它相似JQuery選擇器同樣的語法,get、getIn、set、List等的使用方式,固然它也是可使用 toJS方法轉回來的。

Immutability Helpers出場

gitHub上它對本身的介紹很簡單: Mutate a copy of data without changing the original source —— 在不更改原始源的狀況下改變數據副本。

  與它結緣,是由於它在react官方文檔中出鏡,而被我所寵幸,真的 ,只是由於在人羣中多看了它一眼再也沒能忘掉, 它跟immutable不同,不會有那麼多條條框框約束你,給你自由、給你獨立的空間、給你獨立的思想,讓你想用即用、用之即走~~(泥馬,怎麼有點像張小龍說它的小程序同樣😬),但您放心,它的坑真的比小程序少,API也很簡潔,接下來來看一下,它的基本用法:程序員

  • $push —— 數組;
  • $unshift —— 數組;
  • $splice —— 數組;
  • $set —— 替換/覆蓋/合併原數據;
  • $toggle —— array of strings ,toggles a list of boolean fields from the target object;
  • $unset —— remove the list of keys in array from the target object;
  • $merge —— 合併對象;
  • $apply —— passes in the current value to the function and updates it with the new returned value;
  • $add —— 新增;
  • $remove —— 刪除。
以上基本就是它所有的API了,下面一塊兒來看看,具體用法吧:

$push 的使用 :

  • 看名字就知道它的做用了啦,跟原生的push同樣,不過寫法有一點點不同;
let arr = [1,2,3,4,5,66];
  let arr2 = update(arr,{
    $push : ["a","b","c"], //必定要 []號的形式哦,不能夠 "a";
    [4]:{ // !!index ,能夠指定修改下標的值
      $set:"我是替換過的"
    }
  });
  console.log(arr2);

$unshift 的使用 :

  • 同樣,跟原生的unshift,在原數組開頭處插入,一樣寫法是以一個數組的形式;
let arr = [1,2,3,4,5,66];
  let arr2 = update(arr,{
    $unshift : ["a","b","c"],
    [4]:{
      $set:"我是首席填坑官∙蘇南"  //這裏須要注意,它的操做是在 unshift以前執行的,也就是在原 arr 上查找 第4個下標
    }
  });
  console.log("原始數組",arr);// [1, 2, 3, 4, 5, 66] 相互之間並不會影響
  console.log(arr2); //["a", "b", "c", 1, 2, 3, 4, "我是首席填坑官∙蘇南", 66]

$splice 的使用 :

  • 注意 :數組套數組,start,end, 插入的數據……,;
let arr = [1,2,3,4,5,66];
  let arr2 = update(arr,{
    $splice : [[1,2,[66788,99],{a:123,b:"蘇南"}]], // or [0,1,"從我開始是插入的內容",88,89,90,"後面能夠不少,是數組、對象、字符串都行"]
  });
  console.log(arr2); 

  //複雜一些的用法:
  let obj={
    name:"immutable",
    list :[1,2,[90,55,44,3,22,55],3,4,6,7,8]
  };
  let obj2 = update(obj,{
    list:{
      [2]:value=>update(value,{
        $splice:[[0,2]]  // [90,55,44,3,22,55] => [44, 3, 22, 55]
      })
    }
  });

由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper $splice的使用展現
公衆號:honeyBadger8,immutability-helper $splice的使用展現,格式錯誤的警告

$set 的使用 :

  • 上面已經演示過了,其實有點替換的意思,當有重複的值時,就會覆蓋,沒有就新增,來展現複雜一點的場景,層級深的數據,也不會相互影響;
let obj={
    name:"immutable",
    children:{
      address:"ShenZhen",
      hobby:"@IT·平頭哥聯盟-前端開發"
    }
  };
  let obj2 = update(obj,{
    $set : {name:"immutability-helper",other:"其餘字段,如微信公衆號:honeyBadger8,每週爲你帶來最新分享"}
  });
  let obj3 = update(obj,{
    name:{
      $set : "蘇南"
    },
    children:{
      hobby:{
        $set:"首席填坑官 - javascript"
      }
    }
  });
  console.log("原始數據:",obj); 
  console.log("obj2:",obj2); 
  console.log("obj3",obj3);

公衆號:honeyBadger8,immutability-helper $set的使用展現,1024請不要叫我程序園,我是有溫度的攻城獅

$toggle 的使用:

  • 聽名字,應該就能猜出來,開關切換的意思;
  • Boolean 布爾值的切換,若是你是強制要 Number 類型 的 0、1,那麼使用引方法的時候就要注意了;
let obj={
    name:"immutable",
    a:false,
    b:true,
    c:1,
    d:0
  };
  let obj2 = update(obj,{
    $toggle:['b','a',"c","d"],
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper $toggle的使用展現,1024請不要叫我程序園,我是有溫度的攻城獅

$unset 的使用:

  • 它跟$set相反,有點remove的味道,但又貌似有不一樣的之處,當操做的對象爲object時key是刪除了;而數組array中它的值沒有了,卻保留了下標,不改變數組的長度,刪除數組建議仍是用$splice;請看下圖:
let arr = [1,2,3,4,5,6];
  let obj={
    name:"immutable",
    children:{
      address:"ShenZhen",
      hobby:"寫博客"
    }
  };
  let obj2 = update(obj,{
    $unset : ["name"],
    children:{
      $unset:["address"]
    }
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);

  let arr2 = update(arr,{
    $unset : [1]
  });
  console.log("arr2:",arr2,arr2.length);

由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper $unset的使用展現

$merge 的使用:

  • $merge 跟咱們最愛的Object.assign同樣,作合併操做的,但它比assign優秀不少,深層次拷貝,不會相互影響 :
let arr = [1,2,3,4,5,6];
  let obj={
    name:"immutable",
    children:{
      address:"ShenZhen",
      hobby:"寫博客",
      array:["我不是程序員","切圖崽瞭解一下"],
    }
  };
  let obj2 = update(obj,{
    $merge:{
      arr
    },
    children:{
      array:{
        $merge:{items:["從前有坐山","山裏有個廟"]},
        $splice:[[3,0,"住着一個小和尚"]]
      }
    }
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);

公衆號:honeyBadger8,immutability-helper $merge的使用展現,我是有溫度的攻城獅

$apply 的使用:

  • $apply 基於當前值進行一個函數運算,從而獲得新的值 :
  • 注意 :它必須是一個 function 哦!
let obj={
    name:"immutable",
    children:{
      items:["從前有一坐山"],
      array: [1,2,3,4,5,6],
    }
  };
  let obj2 = update(obj,{
    name:{
      $apply:(val)=>("首席填坑官")
    },
    children:{
      items:{
        $apply:(val)=>{
          console.log("舊值",val);
          return [3,0,"住着一個小和尚"]
        }
      },
      array:{
        $apply:(val)=>(val.reverse()) //必須是一個函數
      }
    }
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);

公衆號:honeyBadger8,immutability-helper $apply的使用展現
由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper $apply的使用展現,必須是function

$remove 的使用:

  • $remove 必定必定 要是使用SetMap 建立的數組:
  • 要刪除的值,必須是數組成存在的,如值不存在則忽略,$remove:[2,666],2會刪除,6則會被忽略;
  • 這個api有點奇怪,正常普通的數組 [],這樣的刪除不了!!;
  • 常見錯誤以下圖:
let obj={
    name:"immutable",
    children:{
      array:new Set([1, 2, 3, 4, 4]),
    }
  };
  let obj2 = update(obj,{
    children:{
      array:{
        $remove:[2],
      },
    }
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);

immutability-helper $remove的使用展現,必須是 new Set Map建立
immutability-helper $remove的使用展現,必須是function,公衆號:honeyBadger8

$add 的使用:

  • $add 跟剛纔的 $remove 同樣要使用Map/Set,$add方法也跟 es6 Map/Set的 add方法一致:
  • 只是寫的時候也要注意一些, [ [] ] ,嵌套!
let obj={
    name:"immutable",
    array:new Map([["a",1],["b",2]]),
  };
  let obj2 = update(obj,{
    array:{
      $add:[["66",56]],
    },
  });
  console.log("原始數據:",obj);
  console.log("obj2:",obj2);
  console.log("獲取key a:",obj2.array.get('a'));

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper $add的使用展現,必須是 new Set Map建立

Immutability Helpers的高階用法:

  • 還能夠自定義方法,如 定義一個 $trinocular 方法,來判斷數組中的值;
  • 只是一個簡單的示例,更多複雜的用法,能夠本身去探索哦 去官方 github 👈
update.extend('$trinocular', function(proportion, original) {
    return  original > 88 ? (original/proportion ): (proportion+original);
  });
  let array =[56,33,55,777,322,444,61,12,34,52,245];
  let array2 = array.map((k,v)=>update(k,{
    $trinocular:2
  }))
  console.log("原始數據:",array);
  console.log("array2:",array2);

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,公衆號:honeyBadger8,immutability-helper 高階用法

總結/結尾:

  以上就是基礎 API 的用法 ,添加了一些官方示例,沒有講到的組合使用,以及使用過程當中,可能出現的一些錯誤,須要留意的地方,更多定製高級用法,有興趣的同窗能夠自行了解一下。es6

  以上就是今天爲你們帶來的分享,它可能沒有 immutable 那麼多功能,但貴在簡潔,不會有太多的約束,如理解有誤之處,歡迎各位大佬糾正,畢竟我還只是個寶寶——新手上路中!🤪。github

  下方是我弄的一個公衆號,歡迎關注,之後文章會第一時間,在公衆號上更新,緣由是以前分享的有兩篇文章,居然被其餘公衆號抄襲了😭,前些天去更新發表的時候,微信提示我文章已經不是原創了檢測到相同的文章,寶寶內心那個涼啊~,果斷申訴告了對方(是一個培訓學校公衆號,好氣哦),補了掘金髮布的連接和截圖日期,萬幸最後勝訴了🤗!👇👇面試

寶劍鋒從磨礪出,梅花香自苦寒來,作有溫度的攻城獅!,公衆號:honeyBadger8

更多文章:

作完小程序項目、老闆給我加了6k薪資~
面試踩過的坑,都在這裏了~
你應該作的前端性能優化之總結大全!
如何給localStorage設置一個過時時間?
手把手教你如何繪製一輛會跑車
如何用CSS3畫出懂你的3D魔方?
SVG Sprites Icon的使用技巧

做者:蘇南 - 首席填坑官
連接: https://honeybadger8.github.i...
交流:91259409五、公衆號: honeyBadger8
本文原創,著做權歸做者全部。商業轉載請聯繫 @IT·平頭哥聯盟得到受權,非商業轉載請註明原連接及出處。
相關文章
相關標籤/搜索