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:稀土掘金 (源链)。感谢您的支持!

您可能感兴趣的

Veille de la semaine #7 de 2018 Déployer cache-control: immutable avec du cache-busting (fr) : Mise en place de l'ent&e...
下一代状态管理工具 immer 简介及源码解析... JS 里面的变量类型可以大致分为基本类型和引用类型,而在使用过程中,引用类型经常会产生一些无法意识到的副作用,所以在现代 JS 开发过程中,大家都有意识的写下断开引用的不可变数据类型。 // 引用...
Facebook 宣布 React、Jest、Flow 和 Immutable.js 将采用 MIT... 因为 BSD +专利的许可证授权在开源社区引发争议和不确定后,Facebook 宣布 它的著名开源项目 React、Jest、Flow 和 Immutable.js 将在下周切换到...
Better Code Disclaimer : everything in this post is my own opinion. However, it’s 100% true and ...
深浅拷贝与react之immutable.js 深拷贝和浅拷贝只针对像Object,Array这样的复杂对象,对于基本的数据类型,则不存在深拷贝和浅拷贝的区别。浅拷贝只是复制了对象的一层属性,而深拷贝则是递归复制了所有的层级。 浅拷贝只能拷贝引...