Immutable 非你不可

版权声明:本文版权归作者所有,转载请注明出处 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.jsseamless-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 的优势

  • 分离了 TimeValue 的概念,降低了数据变化的复杂度。简单的说,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() 比较的是值相等

资料


本篇博客版权归本人所有,若转发请注明来源。

猜你喜欢

转载自blog.csdn.net/Christian_Wen/article/details/81449881