Immutable

Immutable (不可變對象,一旦建立不可更改)

npm install immutable
複製代碼

immutable 能夠基於共享部分對象來建立新的對象 :能夠理解爲兩個對象,相同的地方引用的都是同一部分,是相同的。不一樣的地方是不一樣的。git

let { Map } = require('immutable');
let m1 = Map({ a: 1, b: 2, c: 3 });
console.log(m1.get('a'));//1
let m2 = m1.set('a', '11');
console.log(m2.get('a'));//11
console.log(m1.get('a'));//1
console.log(m1 === m2);//false
複製代碼
  • Immutable Data 就是一旦建立,就不能再被更改的數據。對 Immutable 對象的任何修改或添加刪除操做都會返回一個新的 Immutable 對象
  • Immutable 實現的原理是 Persistent Data Structure(持久化數據結構),也就是使用舊數據建立新數據時,要保證舊數據同時可用且不變
  • 同時爲了不 deepCopy 把全部節點都複製一遍帶來的性能損耗,Immutable 使用了 Structural Sharing(結構共享),即若是對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享
let { Map,fromJS } = require('immutable');
let m1 = fromJS({ a: 1, b: { c: 1 } });
let m2 = m1.set('a', 11);
console.log(m1.get('a'));//1
console.log(m2.get('a'));//11
console.log(m1.b === m2.b);//true
let m2 = m1.setIn(['b', 'c'], 'c');//修改多級
let m2 = m1.updateIn(['b', 'c'], val => val + 2);//updateIn,傳入一個回調
console.log(m2.getIn(['b', 'c']));//獲取多級
複製代碼

問題:immutable雖然很強大,但使用與普通js不同,壓縮後庫仍是比較大的20多k。github

第二種immutable類庫:seamless-immutable

使用Object.defineProperty擴展了 JavaScript的Array和Object對象來實現,只支持 Array 和 Object 兩種數據類型npm

let Immutable=require('seamless-immutable');
let objA=Immutable({info: {age: 8}});
let objB=objA.merge({info: {age: 9}});
console.log(objA.info.age);
console.log(objB.info.age);
複製代碼

優缺點:用法簡單,比較小。可是功能不強大。數組

Immutable優點bash

下降複雜度數據結構

let obj = immutable({ age: 8 });
handle(obj);
console.log(obj.age);//8

function handle(obj) {
    obj.age = 100;
}
//無論handle(obj);如何修改,obj.age始終爲8
複製代碼

節約內存:共享相同部分less

方便回溯:撤銷性能

原理解析

function Map(obj) {
    return {
        set(key, val) {
            let newObj = { ...obj };
            newObj[key] = val;
            return Map(newObj);
        },
        get(key) {
            return obj[key];
        }
    }
}
let m1 = Map({ a: 1, b: 2, home: { name: 'beijing' } });
let m2 = m1.set('b', '22');
console.log(m2.get('b'));
複製代碼

經常使用API

//Map()  原生object轉Map對象 (只會轉換第一層,注意和fromJS區別)
immutable.Map({name:'danny', age:18})

//List()  原生array轉List對象 (只會轉換第一層,注意和fromJS區別)
immutable.List([1,2,3,4,5])

//fromJS()   原生js轉immutable對象  (深度轉換,會將內部嵌套的對象和數組所有轉成immutable)
immutable.fromJS([1,2,3,4,5])    //將原生array  --> List
immutable.fromJS({name:'danny', age:18})   //將原生object  --> Map

//toJS()  immutable對象轉原生js  (深度轉換,會將內部嵌套的Map和List所有轉換成原生js)
immutableData.toJS();

//查看List或者map大小
immutableData.size  或者 immutableData.count()

// is()   判斷兩個immutable對象是否相等
immutable.is(imA, imB);

//merge()  對象合併
var imA = immutable.fromJS({a:1,b:2});
var imA = immutable.fromJS({c:3});
var imC = imA.merge(imB);
console.log(imC.toJS())  //{a:1,b:2,c:3}

//增刪改查(全部操做都會返回新的值,不會修改原來值)
var immutableData = immutable.fromJS({
    a:1,
    b:2,
    c:{
        d:3
    }
});
var data1 = immutableData.get('a') //  data1 = 1
var data2 = immutableData.getIn(['c', 'd']) // data2 = 3   getIn用於深層結構訪問
var data3 = immutableData.set('a' , 2);   // data3中的 a = 2
var data4 = immutableData.setIn(['c', 'd'], 4);   //data4中的 d = 4
var data5 = immutableData.update('a',function(x){return x+4})   //data5中的 a = 5
var data6 = immutableData.updateIn(['c', 'd'],function(x){return x+4})   //data6中的 d = 7
var data7 = immutableData.delete('a')   //data7中的 a 不存在
var data8 = immutableData.deleteIn(['c', 'd'])   //data8中的 d 不存在
複製代碼
相關文章
相關標籤/搜索