Immutable

综合技术 2018-04-10 阅读原文

npm install immutable

immutable 可以基于共享部分对象来创建新的对象 :可以理解为两个对象,相同的地方引用的都是同一部分,是相同的。不同的地方是不同的。

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。

第二种immutable类库:seamless-immutable

使用Object.defineProperty扩展了 JavaScript的Array和Object对象来实现,只支持 Array 和 Object 两种数据类型

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优势

降低复杂度

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

function handle(obj) {
    obj.age = 100;
}
//不管handle(obj);如何修改,obj.age始终为8

节约内存:共享相同部分

方便回溯:撤销

原理解析

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 不存在
稀土掘金

责编内容by:稀土掘金阅读原文】。感谢您的支持!

您可能感兴趣的

处理 JavaScript 复杂对象:深拷贝、Immutable & Immer... 我们知道 js 对象是按共享传递( call by sharing )的,因此在处理复杂 js 对象的时候,往往会因为修改了对象而产生副作用———因为不知道谁还引用着这份数据,不知道这些修改会影响到谁。因此我们经常会把对象做一次拷贝再放到...
Spread Operator Tricks I recently came across some handy patterns using the spread operator so I thought I’d write up a quick blog post sh...
Qim: Select from Your Immutable JavaScript Cake an... If you're reading this article, you're probably wondering a few things: What the heck is Qim? What the hec...
Intro to the zip function this post was originally published on my Github Pages site on September 19th, 2017 Now that we have covered the ...
Immutable.js and Lazy Evaluation At PSPDFKit, we have a strong bias toward functional programming, which emphasizes immutability. Using immuta...