ImmutableJS

对Immutable对象进行修改、添加或删除,都会返回一个新的对象

实现原理
持久化的数据结构,举个例子

ImmutableJS_第1张图片
1628e77dc419816b.gif

如上图,当改变 旧数据 的一个节点时(改变的节点变成新的黄色的节点),会保证旧数据可用且不变,只修改旧数据的该节点和受它影响的父节点,其他节点,新数据和旧数据共享!

这样,就避免了深拷贝把所有节点都复制一遍带来的性能损耗。


最重要的三种数据结构
Map:对应Object
List:有序可重复列表,对应Array
ArraySet:无序 不可重复列表


优点
1、降低了“可变”带来的复杂度
因为immutable data是一旦创建,就不可更改的数据,所以data是不可变的,比如:

let aa={key:"value"}
change(aa)
console.log(aa.key)

打印的仍然是 value,不必担心 change(aa)对它做了什么。

2、节省内存
使用结构共享 复用了内存(见上图说明),而且没有被引用的对象会被GC(garbage collection->
垃圾回收)

3、实现 撤销/重做,复制/粘贴,时间旅行 功能轻而易举
因为每次数据都不一样,只需将 每次数据存到 数组里,这样 想回退到哪里,就拿出对应的数据即可。

4、并发安全
由于数据是不可变的,所以就不需要 并发锁,但JS是单线程运行,未实际应用。

5、拥抱 函数式编程
只要输入一致,输出必然一致。


缺点:易与原生对象混淆


immutablejs的 is
为了直接比较对象的值,Immutable提供了 is(a,b) 来做“值”比较

is(a,b)比较的是两个对象的hashCode或valueOf,Immutable内部使用了trie结构,只要两个对象的 hashCode相等,值就是一样的,不需要深度遍历。


Immutable的getIn和setIn
由于cursor已被immutablejs废弃,改成了getIn和setIn来访问和改变深层数据的引用

let data=Immutable.fromJS({
                            a: {
                               b: {
                                   c:1
                                   }
                                }
                            })

let newdata=data.getIn(['a','b'])
newdata.get('c')  //-->1
newdata = newdata.update('c', val => val+1)
newdata.get('c') //-->2

更多的api请参考 这里
注意:在使用set,update等更新数据的操作后,一定要 a=a.set(xx),否则,数据a不会改变值!!

附自己实践的一段代码(结合了redux):

//更新头像
    let data=state.get('data')
    let oneuser=data.find((item, index,array) => {
      return item.get('userid')===action.id
    })
    oneuser=oneuser.set('picurl',action.picurl)
    let index=data.findIndex((value,index,array)=>{
      return value.get('userid')===action.id
    })
    data=data.set(index,oneuser)
    return state.merge({
      data: data
    });

(完)

你可能感兴趣的:(ImmutableJS)