immutable及其常用用法

简介: immutable及其常用用法

什么是 Immutable Data

1.Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象

2.Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变

3.同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing····(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

打印immutableJS看看有什么东西


一个说明不可变的例子

// 原生对象
let a1 = {
    b: 1,
    c: {
        c1: 123
    }
};
let b1 = a1;
b1.b = 2;
console.log(a1.b, b1.b); // 2, 2
console.log(a1 === b1); // true
console.log(a1.c === b1.c); // true
// immutable.js 的Map
let a2 = Immutable.fromJS({
    b: 1,
    c: {
        c1: 123
    }
});
let b2 = a2.set('b', 2);
// 对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象
console.log(a2.get('b'), b2.get('b')); // 1, 2  对象 a2 的 b 值并没有变成2。
console.log(a2 === b2); //  false
//如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。
console.log(a2.get('c') === b2.get('c')); //true

为什么要在React.js中使用Immutable

1.它是一个完全独立的库,无论基于什么框架都可以用它。意义在于它弥补了Javascript 没有不可变数据结构的问题

2.由于是不可变的,可以放心的对对象进行任意操作。在React开发中,频繁操作state对象或是store,配合immutableJS快、安全、方便。

熟悉React.js的都应该知道,React.js是一个UI = f(states)的框架,为了解决更新的问题,React.js使用了virtual dom,virtual dom通过diff修改dom,来实现高效的dom更新。但是有一个问题。当state更新时,如果数据没变,你也会去做virtual dom的diff,这就产生了浪费。这种情况其实很常见,当然你可能会说,你可以使用PureRenderMixin来解决呀,PureRenderMixin是个好东西,我们可以用它来解决一部分的上述问题,但PureRenderMixin只是简单的浅比较,不使用于多层比较。那怎么办?自己去做复杂比较的话,性能又会非常差

方案就是使用immutable.js可以解决这个问题。因为每一次state更新只要有数据改变,那么PureRenderMixin可以立刻判断出数据改变,可以大大提升性能.

Immutable 优点

1.Immutable 降低了 Mutable 带来的复杂度

可变(Mutable)数据耦合了 Time和 Value 的概念,造成了数据很难被回溯

节省内存

2.Immutable.js 使用了 Structure Sharing 会尽量复用内存,甚至以前使用的对象也可以再次被复用。没有被引用的对象会被垃圾回收

import { Map} from 'immutable';
let a = Map({
  select: 'users',
  filter: Map({ name: 'Cam' })
})
let b = a.set('select', 'people');
a === b; // false
a.get('filter') === b.get('filter'); // true


3.Undo/Redo,Copy/Paste,甚至时间旅行这些功能做起来小菜一碟

因为每次数据都是不一样的,只要把这些数据放到一个数组里储存起来,想回退到哪里就拿出对应数据即可,很容易开发出撤销重做这种功能。


4.并发安全

传统的并发非常难做,因为要处理各种数据不一致问题,因此『聪明人』发明了各种锁来解决。但使用了 Immutable 之后,数据天生是不可变的,并发锁就不需要了。


5.拥抱函数式编程

Immutable 本身就是函数式编程中的概念,纯函数式编程比面向对象更适用于前端开发。因为只要输入一致,输出必然一致,这样开发的组件更易于调试和组装。

Immutable 缺点

  1. 需要学习新的 API
  2. 增加了资源文件大小
  3. 容易与原生对象混淆

Immutable 的几种数据类型

1.List: 有序索引集,类似JavaScript中的Array。

2.Map: 无序索引集,类似JavaScript中的Object。
3.OrderedMap: 有序的Map,根据数据的set()进行排序。

4.Set: 没有重复值的集合。

5.OrderedSet: 有序的Set,根据数据的add进行排序。

6.Stack: 有序集合,支持使用unshift()和shift()添加和删除。

7.Range(): 返回一个Seq.Indexed类型的集合,这个方法有三个参数,start表示开始值,默认值为0,end表示结束值,默认为无穷大,step代表每次增大的数值,默认为1.如果start = end,则返回空集合。

8.Repeat(): 返回一个vSeq.Indexe类型的集合,这个方法有两个参数,value代表需要重复的值,times代表要重复的次数,默认为无穷大。

9.Record: 一个用于生成Record实例的类。类似于JavaScript的Object,但是只接收特定字符串为key,具有默认值。

10.Seq: 序列,但是可能不能由具体的数据结构支持。

11.Collection: 是构建所有数据结构的基类,不可以直接构建

上面那么多常用的也就是 List和Map

immutable常用API ------ List

List是有序的密集型集合,使用场景太多了,是使用immutable必不可少的一个数据结构,学习起来也是非常简单,类似于JS的数组(Array)。如果你熟练掌握了数组的原生的方法,则你在学习该List则会很简单,如果还不太熟悉,请看我的上一篇数组的常用方法。注:在这里定义数据结构采用typescript,代码片段采用ES6的块级作用域避免因变量相同影响其他代码,但是你即使不会使用ts也不会妨碍你学习。学习旅途开始了,代码撸起来。

脑图

相关文章
|
1月前
|
存储 关系型数据库 MySQL
lodash库——封装好的collection集合函数
lodash库——封装好的collection集合函数
49 0
|
1月前
|
存储 JavaScript 前端开发
TypeScript 中的 Map 对象定义、基本操作和常见用法
TypeScript 中的 Map 对象定义、基本操作和常见用法
250 7
|
存储 关系型数据库 MySQL
lodash库_封装好的collection集合函数
lodash库_封装好的collection集合函数
121 0
|
JavaScript 前端开发 网络架构
【ES6】函数的参数、Symbol数据类型、迭代器与生成器
【ES6】函数的参数、Symbol数据类型、迭代器与生成器
87 0
|
索引
forEach用法与map用法区别
forEach用法与map用法区别
159 0
ES6中 Symbol 的基础学习,迭代器和生成器的基本用法
迭代器为所有数据结构提供了统一的访问机制。只要为数据结构部署了接口,就可以进行遍历操作。
116 0
|
编译器 C++
C++关键字--mutable
C++关键字--mutable
176 0
C++关键字--mutable
ES6新特性(3)之Symbol/Set/WeakSet
ES6新特性(3)之Symbol/Set/WeakSet
|
存储 Java
ES6新特性(2)之Symbol/Set/WeakSet
ES6新特性(2)之Symbol/Set/WeakSet
|
前端开发
less语法(一)变量与extend
less语法(一)变量与extend