immutable.js 和 immer

作者: IOneStar | 来源:发表于2022-04-05 14:20 被阅读0次

不可变数据类型

immutable,副作用,纯函数关键词解释:

  • immutable: 不可变数据
  • 副作用:调用函数,同时对主函数产生了附加的影响,比如修改全局变量,改变参数。
    如何避免,创建不可变数据类型,在一次更新过程中不应该改变原有对象,需要返回一个新的对象
  • 纯函数:无副作用的函数

js 中的对象一般是可变的,因为使用了引用赋值,虽然可以节约内存,但是会有一些隐患。一般做法使用浅拷贝和深拷贝来避免修改,但是这样会造成 CPU 和内存浪费。

为了解决这个问题,出现了 immutable.js 和 immer

immutable.js 库

immutable.js 实现原理:Persistent Data Structure(持久化数据结构)。

  • 使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点否复制一遍带来的性能问题, immutable 使用了 Structural Sharing(结构共享),即如果对象树中的一个节点改变,只修改这个节点和受它影响的父节点,其他节点共享。
  • immutable-js 使用了另一套数据结构 api,它会将原生数据类型都转化为 immutable-js 内部对象。

内部实现了一套 Persistent Data Structure,还有很多易用的数据类型像 CollectionListMapSetRecordSeq。有非常全面的mapfiltergroupByreduce``find函数式操作方法。同时 API 也尽量与 Object 或 Array 类似。

缺点:

  1. 需要学习新的 API
  2. 容易与原生对象混淆。
    Immutable 中的 Map 和 List 虽对应原生 Object 和 Array,但操作非常不同,比如你要用 map.get('key') 而不是 map.keyarray.get(0) 而不是 array[0]。另外 Immutable 每次修改都会返回新对象,也很容易忘记赋值。

和 redux 的配合使用,redux 简化了 Flux 中多个 store 的概念,只有一个 store,数据操作通过 reducer 使用。reducer 就是要接受一个纯函数。

const reducer = function (state, action) {
  // ...
  return new_state;
};

immer

mobx 作者写的一个 immutable 库,核心实现利用 es6 的 proxy。
immer 使用原生数据结构的 api,而不像 immutable-js 转化为内置对象的 api。
学习成本低,就是把之前的操作放置到 produce 函数的第二参数函数中去执行。
原理:使用了一个 ES6 的新特性 Proxy 对象。深层嵌套对象的结构化共享的处理

proxy 具体可以看 Proxy

var proxy = new Proxy(target, handler);
  • target 参数表示所要拦截的目标对象。如果没有 Proxy 的介入,操作原来要访问的就是这个对象
  • handler 参数也是一个对象,用来定制拦截行为。对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作

Proxy 无法 polyfill,所以 immer 在不支持 Proxy 的环境中,使用 Object.defineProperty 来进行一个兼容。

immer 维护一份 state 在内部,劫持所有操作,内部来判断是否有变化从而最终决定如何返回。

相关文章

网友评论

    本文标题:immutable.js 和 immer

    本文链接:https://www.haomeiwen.com/subject/ktomcrtx.html