You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
const{ List }=require('immutable');// 将对象转为 Immutable List 数据结构';constlist1=List([1,2]);// Immutable List 的方法,类似于 js arrayconstlist2=list1.push(3,4,5);// [1,2,3,4,5]constlist3=list2.unshift(0);// [0,1,2,3,4,5]constlist4=list1.concat(list2,list3);// [1,2,3,4,5,0,1,2,3,4,5]//push, set, unshift or splice 都可以直接用,返回一个新的immutable对象
参考文章:
Immutable 详解及 React 中实践
React性能优化的中流砥柱——Immutable数据流
前言
JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。JS 对象的引用赋值特点虽然可以大大节约栈内存空间,但当应用复杂后,这就造成了非常大的隐患,Mutable 带来的优点变得得不偿失。为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。Immutable 可以很好地解决这些问题。
Immutable
immutable 数据一种利用结构共享形成的持久化数据结构,一旦有部分被修改,那么将会返回一个全新的对象,并且原来相同的节点会直接共享。
每次修改一个 immutable 对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据。
immutable 对象数据内部采用是多叉树的结构,如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。如图:
优点
可变(Mutable)数据耦合了 Time 和 Value 的概念,造成了数据很难被回溯。
Immutable 能够完整记录历史的状态,因此我们不用担心 Immutable 数据会在某些地方被改变。它就像一个“快照”,你只要保留它,就能在之后的任何地方访问到历史的记录。
Immutable.js 使用了 Structure Sharing 会尽量复用内存,甚至以前使用的对象也可以再次被复用。没有被引用的对象会被垃圾回收。Structure Sharing 避免了深拷贝对内存的占用。
上述代码中,
filter
属性没有改变,因此复用了该节点下的对象。Immutable 本身就是函数式编程中的概念,纯函数式编程比面向对象更适用于前端开发。因为只要输入一致,输出必然一致,这样开发的组件更易于调试和组装。
缺点
这点是我们使用 Immutable.js 过程中遇到最大的问题。写代码要做思维上的转变。
虽然 Immutable.js 尽量尝试把 API 设计的原生对象类似,有的时候还是很难区别到底是 Immutable 对象还是原生对象,容易混淆操作。
Immutable 中的 Map 和 List 虽对应原生 Object 和 Array,但操作非常不同,比如你要用
map.get('key')
而不是map.key
,array.get(0)
而不是array[0]
。另外 Immutable 每次修改都会返回新对象,也很容易忘记赋值。如何避免“混淆”?
Immutable.fromJS
而不是Immutable.Map
或Immutable.List
来创建对象,这样可以避免 Immutable 和原生对象间的混用。immutable 文档
参考 Immutable-js 官方文档。
常用的方法如下:
Redux + Immutable
未使用immutable时,一旦当newStateList中的类型较为复杂(包含引用类型),且需要修改newStateList时,就会发生报错,因为
[...xxx, ...xxx]
是浅拷贝,会影响原来的状态。Redux 结合 Immutable 使用,通过store中传递过来的老状态prevState先转化为immutable对象,对深拷贝之后的对象,再进行修改等操作时,不会影响原状态,最后再通过toJS()转换为js对象即可。
The text was updated successfully, but these errors were encountered: