前端技术整理之Immutable

本文介绍 Immutable.js 的核心概念与常用数据结构,如 List、Map 和 Set,并探讨其在 React 和 Redux 中的应用价值。此外,还提供了如何利用 Immutable.js 进行高效数据操作的示例。

前言

项目中一直有用到Immutable, 它和ReactRedux可以说是同时期的产物,ImmutableRedux结合起来效果会很好。现在对其做一些总结整理。

概述

Immutable data一经创建就无能再被更改。任何修改删除等操作都会返回一个新的Immutable对象。这就和Redux的要求很相似了,使用Redux的时候,要求我们只能有一个store,每次修改就要返回一个新的store。Immutable是基于Persistent Data Structure(持久化数据结构)实现的,在使用旧数据创建新数据时,保证旧数据的可用且不变,使用数据共享(structural sharing),只改变其中有变化的节点以及受影响的父节点,减少需要复制和缓存的数据(如果将对象看成一个个树结构的话), 如下图:

Immutable的使用

数据类型
1. List

List are ordered indexed dense collections,much like a JavaScript Array

List是一个有序的索引集合,就像JavaScript中的Array

与JavaScript中Array不同的是,它不会去判断某个下标的元素是不是被定义了,它都会从0开始访问。

构造及主要方法:

  1. List(): 创建一个Immutable List集合,包括提供的数据。
  2. isList(): 判断一个集合是否是Immutable 的 List集合。
  3. of(): 将参数中的所有值创建成一个List集合。
  4. delete(): 根据下标删除list中的元素返回新集合。
  5. insert(): 根据下标插入元素。
  6. clear():将集合中的元素清空。
  7. push():添加元素。
  8. setIn(): 深层次修改制定元素。
const {
	List
} from 'immutable';
const list = List([ 0, 1, 2, List([ 3, 4 ])])
list.setIn([3, 0], 999);
// List [ 0, 1, 2, List [ 999, 4 ] ]
复制代码
  1. deleteIn(): 深层次删除制定元素。
  2. concat(): 合并List集合。

详细的方法请看官方文档。

2. Map

Map: 无序的索引集,像Java中的Map

构造:

  1. Map(): 创建一个新的 Immutable Map
3. 其他

OrderedMap

class OrderedMap<K, V> extends Map<K, V>

Orderedmap: 有序的Map,根据数据的set()进行排序

Set

A Collection of unique values with O(log32 N) adds and has

Set: 没有重复值的集合

OrderSet

A type of Set that has the additional guarantee that the iteration order of values will be the order in which they were added

一个有序的Set集合,通过add进行排序。

Stack

Stacks are indexed collections which support very efficient O(1) addition and removal from the front using unshift(v) and shift().

堆栈:有序的集合,支持 unshift()和shift进行添加和删除。

Range()

Returns a Seq.Indexed of numbers from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity. When start is equal to end, returns empty range.

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

Repeat()

Returns a Seq.Indexed of value repeated times times. When times is not defined, returns an infinite Seq of value.

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

Record

A record is similar to a JS object, but enforces a specific set of allowed string keys, and has default values.

类似JS中的Object,但是只接受特定字符串为key,具有默认值。

Seq

Seq describes a lazy operation, allowing them to efficiently chain use of all the higher-order collection methods (such as map and filter) by not creating intermediate collections.

Seq 是惰性的,尽可能少的响应函数调用。一旦呗创建,就无法被修改,只能返回一个新的Seq。

Collection

The Collection is a set of (key, value) entries which can be iterated, and is the base class for all collections in immutable, allowing them to make use of all the Collection methods (such as map and filter)

所有数据结构的基类,不可以直接构建。

一些主要的方法

SetIn()

Returns a copy of the collection with the value at the key path set to the provided value.

通过key值设置属性值,返回一个拷贝的数据

const {
	setIn
} from 'immutable'

const a = {x: { y: { Z: '1' } }}
setIn(a, ['x', 'y', 'z'], '78')
console.log(a) // { x: { y: { z: '78' }}}
复制代码

merge()

Returns a copy of the collection with the remaining collections merged in.

在原数据的基础上,合并成一个集合。

例如:

const {
	merge
} from 'immutable'

const a = { x: 1, y: 2 }
const b = { y: 9, z: 10 }
merge(a, b) // { x: 1, y: 9, z: 10 }
复制代码

merge会出现数据覆盖的情况,注意先后顺序。

groupBy()

Returns a Collection.Keyed of Collection.Keyeds, grouped by the return value of the grouper function.

根据条件分组,分成不同的集合,返回值是OrderMap

例如:

import Immutable from 'immutable'
const a = {b: {a5: 333}, a: {a5: 333}, c: {a5: 334}, d: {a5: 334}}
const b = Immutable.fromJS(a)
const c = b.groupBy((value) => { return value.get('a5') })
console.log('c', c)
// OrderedMap  {333: {b: {a5: 333}, a: {a5: 333}}, 334: {c: {a5: 334}, d: {a5: 334}}}
复制代码

fromJS()

Deeply converts plain JS objects and arrays to Immutable Maps and Lists.

将JS数据转换成Immutable数据

zip()

Returns a List "zipped" with the provided collection.

循环插入,长度以后者为准

例如:

const a = List([1, 2, 3])
const b = List([5, 6])
const c = a.zip(b) // List[[1, 5], [2, 6]]
复制代码

map()

Returns a new List with values passed through a mapper function.

循环操作,返回一个新的List

例如:

console.log(Immutable.fromJS([1,2,3]).map((value) => { return value * 2 }).toJS())
// [2, 4, 6]
复制代码

filter()

Returns a new List with only the values for which the predicate function returns true.

根据条件循环过滤

例如:

console.log(Immutable.fromJS([1, 2, 3, 4, 5]).filter((value, index, array)=>{
    return value % 2 === 0;
}).toJS()); // [2, 4]
复制代码

Immutable的优缺点

  1. 使用的是数据共享,减少内存的消耗。
  2. Undo/Redo,Copy/Paste,甚至时间旅行这些功能做起来小菜一碟
  3. 并发安全
  4. Immutable是一种函数式编程的概念

总结

其实还有很多其他的方法以及数据类型,有很多就像JavaScript里用到的方法,我这就不一一介绍了,只是把我经常用到的再这个说下。有兴趣的可以去看下官方文档,虽然有点难懂,但是还是很全的。

参考资料

Immutable官方文档

Immutable 详解及 React 中实践

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值