版权声明:本文版权归作者所有,转载请注明出处 https://blog.csdn.net/Christian_Wen/article/details/81449881
Shared mutable state is the root of evil. – Pete Hunt
前言
本篇博客是我上周在公司做的技术分享 - Immutable.js
实战经验的书面总结
抛开复杂的底层算法,不看繁冗的API文档,这篇博客主要介绍一下Immutable到底是什么,以及为什么我们需要使用immutable.js
。
简介
Immutable Data
就是一旦创建便不能被修改的数据Immutable Data
的任何修改或添加删除操作都会返回一个新的Immutable
对象Immutable Data
的原理是 持久化数据结构Immutable Data
使用结构共享来解决内存- 流行的库有两个:
immutable.js
和seamless-immutable
Mutable 数据的缺陷
- 在
JavaScript
中,Object
这个东西实际上是Mutable
的,举个简单的例子:
### 当我回忆前女友时,现女友变成了前女友,这下子麻烦大了 ###
const girlfriend = {
name: 'Molly',
age: 22
}
const exGirlfriend = girlfriend;
exGirlfriend.name = 'Olwen';
exGirlfriend === girlfriend // true
- 当进行简单的赋值操作时,你对任何一方的修改都会导致源数据的变化,理解起来非常的匪夷所思。
- 正所谓物有本末,事有终始,一切之不合理皆有其缘由,究其原因,是存储数据的机制导致的,该部分将在下面详细描述。
数据存储 — 内存图
- 简单类型数据存在内存栈中,复杂类型数据存在内存堆中,对复杂类型数据的操作实际上是对地址的操作…这句耳熟能详的话人人都能背诵,但是图片一直是交流的最佳捷径,于是我
绘制了
这张内存图跟大家分享。
- 左边就是
内存栈
,右边则是内存堆
。可以看到,栈是有严格的结构的,显然这样的存储对于对象来说非常麻烦。因为你存一个对象,可能会在后续中给他加若干个属性,换句话说,一个对象所需要的内存是不确定的。如果对象存在栈中,每对他的属性进行一次修改,那么就必然会影响到其余的元素进行挪动,十分消耗性能。 - 于是将其存在堆中,在栈中仅仅是对其地址进行引用,如此,不管该对象如何增删改查,地址永远不变。我们所谓的
=
赋值和===
全等则均是对其地址进行操作。例如a = b
则是将b
的引用地址赋给a
,对地址产生的对象实则没有任何改变,a === b
则也是对其地址进行比较,如此这般,则能很好地理解Mutable到底是什么。 - 学会了绘制内存图,则一切
赋值比较
操作皆有迹可循。
immutable.js 的优势
- 分离了
Time
和Value
的概念,降低了数据变化的复杂度。简单的说,Time
对应Value
而不是改变它。 - 新旧数据的部分结构共享,
immutable.js
生成的数据中,只关注做了改动的部分,未作改动的部分则继续保留。
import { Map } from ‘immutable’;
const girlfriend = Map({
name: ‘Molly’,
info: Map({age: 22})
})
const exGirlfriend = girlfriend.set(‘name’, ’Olwen’);
girlfriend === exGirfriend // false
girlfriend.get(‘age’) === exGirlfriend.get(‘age’) // true
- 每次操作的数据都能被获取,可以进行任何匪夷所思的操作。
- 对于高并发数据处理非常安全,但是
JavaScript
是一门单线程语言,然并卵。 No side effect, Pure
React中 immutable.js 上链指南
feature
React
的本质:UI = Render(data)
- 提供了两个类:
Component PureComponent
React
提供可供优化的Hook
:getDerivedStateFromProps( nextProps,prevState )
问题
PureComponent
只能进行浅比较,Component
则依赖于getDerivedStateFromProps
函数PureComponent
进行的浅比较应当是深度为1
的比较,而传统意义上的浅比较则是深度为0
的引用地址比较。getDerivedStateFromProps
实质上依旧是 单纯的数据比较- 只要涉及到比较,
一定
会涉及到性能问题
处理
imuutable
优化了两个对象之间的值比较,无须使用深克隆去递归遍历,Immutable.is()
· 帮你解决比较问题- 请注意,即使两个
Immutable
数据完全一致,使用传统意义上的===
去比较依旧为false
- 此外,
Immutable.is(a, b)
中,如果b
是由a
修改(Immutable.setIn()
)得到,则性能比b由Immutable.fromJS()
得到的要高。 - 请注意,
Immutable.is()
比较的是值相等
资料
本篇博客版权归本人所有,若转发请注明来源。