RN - immutable 简单学习、用法(转)
转自 - https://segmentfault.com/a/1190000002909224
转自 - https://zhuanlan.zhihu.com/purerender/20295971
转自 - https://www.w3cplus.com/javascript/immutable-js.html
(转)什么是 Immutable Data
网络配图.gifImmutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。请看下面动画:
Immutable有什么用
Immutable Data是指一旦被创造后,就不可以被改变的数据。
通过使用Immutable Data,可以让我们更容易的去处理缓存、回退、数据变化检测等问题,简化我们的开发
Immutable的优点
- 使得数据可以被回溯,由于每次更改都不改变原数据,类似撤回等功能很容就可以实现
- 节省内存,Immutable.js 使用了 Structure Sharing 会尽量复用内存,甚至以前使用的对象也可以再次被复用。没有被引用的对象会被垃圾回收。
- Immutable 本身就是函数式编程中的概念,纯函数式编程比面向对象更适用于前端开发。因为只要输入一致,输出必然一致,这样开发的组件更易于调试和组装。
使用 Immutable 的缺点
- 需要学习新的 API
- 增加了资源文件大小
- 容易与原生对象混淆
这点是我们使用 Immutable.js 过程中遇到最大的问题。写代码要做思维上的转变。
虽然 Immutable.js 尽量尝试把 API 设计的原生对象类似,有的时候还是很难区别到底是 Immutable 对象还是原生对象,容易混淆操作。
Immutable.js 的 API 主要包含以下几部分:
-
formJS()
,将 JavaScript Object 和 Array 彻底转换为 Immutable Map 和 List -
is()
,与Object.is()
类似都是对值的比较,但它会将 Immutable Iterable 视为值类型数据而不是引用类型数据,如果两个 Immutable Iterable 的值相等,则返回 true。与Object.is()
不同的是,is(0, -0)
的结果为true
-
List
,有序索引集,类似于 JavaScript 中的 Array -
Map
,无序 Iterable,读写 Key 的复杂度为O(log32 N)
-
OrderedMap
,有序 Map,排序依据是数据的 set() 操作 -
Set
,元素为独一无二的集合,添加数据和判断数据是否存在的复杂度为O(log32 N)
-
OrderedSet
,有序 Set,排序依据是数据的 add 操作。 -
Stack
,有序集合,且使用unshift(v)
和shift()
进行添加和删除操作的复杂度为O(1)
-
Range()
,返回一个 Seq.Indexed 类型的数据集合,该方法接收三个参数(start = 1, end = infinity, step = 1)
,分别表示起始点、终止点和步长,如果 start 等于 end,则返回空的数据结合 -
Repeat()
,返回一个 Seq.indexed 类型的数据结合,该方法接收两个参数(value,times)
,value 表示重复生成的值,times 表示重复生成的次数,如果没有指定times
,则表示生成的Seq
包含无限个value
-
Record
,用于衍生新的 Record 类,进而生成 Record 实例。Record 实例类似于 JavaScript 中的 Object 实例,但只接收特定的字符串作为 key,且拥有默认值 -
Seq
,序列(may not be backed by a concrete data structure) -
Iterable
,可以被迭代的(Key, Value)
键值对集合,是 Immutable.js 中其他所有集合的基类,为其他所有集合提供了 基础的 Iterable 操作函数(比如map()
和filter
) -
Collection
,创建 Immutable 数据结构的最基础的抽象类,不能直接构造该类型
例:Record 用法
Record 在表现上类似于 ES6 中的 Class,但在某些细节上还有所不同。通过 Record() 可以创建一个新的 Record 类,使用该类可以创建具体的 Record 实例,该实例包含在 Record() 构造函数中声明的所有属性和默认值。如果 Record 实例中的某个属性被删除了或者没有声明,则只会将实例中的属性值设置为默认值
创建 Record 实例 const A = Record({ a: 1, b: 2 });
const r = new A({ a: 3 });
// => Record { "a": 3, "b": 2 }
删除实例属性 const rr = r.remove('a');
// => Record { "a": 1, "b": 2 }
此外,Record 实例还具有扩展性:
class ABRecord extends Record({a:1,b:2}) {
getAB() {
return this.a + this.b;
}
}
var myRecord = new ABRecord({b: 3})
myRecord.getAB()
// => 4
import Immutable from 'immutable';
const ARecord = Immutable.Record({
myID: null,
myName: null,
myPhone: null,
myAddress: null,
myAge: null,
mySex:null,
});
export default class MyRecord extends ARecord {
getMyAge(){
return 18;
}
}
let myrecord = new MyRecord({
myID: 737427428,
myName: '张三',
myPhone: '1234567890',
myAddress: '北京',
myAge: 18,
mySex:'男',
// 如果其中一个属性没声明,就是默认的 null
});
myrecord.abc();