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