Immutable.fromJS的描述是:



但这是错误的。我有一个具有以下结构的对象。大写的项目是ES6类。

Foo
  prop1
  prop2
  bars
    Bar
      prop1
      prop2
    Bar
      prop1
      prop2
  bazes
    Baz
      prop1
      prop2
      bars
        Bar
          prop1
          prop2
        Bar
          prop1
          prop2
    Baz
      prop1
      prop2
      bars
        Bar
          prop1
          prop2
        Bar
          prop1
          prop2
Immutable.fromJS(foo)的结果是一个Map。数组barsbazesList。但是,这些列表中的每个元素仍然是普通(ES6)对象。每个Baz的bars属性是一个数组,而不是一个列表。

我是在做错什么,还是文档不正确?

也许ES6对象不支持深度功能?如果是这种情况,我如何使我的物体深不可变性?

更新:

这可行,但感觉有点毛病:Immutable.fromJS(JSON.parse(JSON.stringify(foo)))

最佳答案

docs for fromJS 的第一句话是:



如果Foo,Bar和Baz是ES6类,则它们既不是纯JS对象也不是数组-它们是类的实例。所以,不,文档不是不正确的。

顺便说一句,如果Immutable.fromJS自动将遇到的任何对象转换为纯JS对象(如您似乎期望的那样),那么对于大多数用户而言这将是非常令人惊讶的行为,并且根本不是所希望的。

但是,由于这是您想要的行为,因此您将很高兴知道不可变Wiki具有a section on this exact topic,为便于后继,我将在此处复制:



那很简单。而且的确,它的运行完全如所 promise 的那样,如运行以下代码片段所见。

class Foo {
  constructor(name, ...children) {
    this.name = name;
    this.children = children;
  }
}

class Bar extends Foo {}
class Baz extends Foo {}

const myBar = new Bar("myBar", new Baz("myBaz1"), new Baz("myBaz2"));
const myFoo = new Foo("myFoo", myBar);

function fromJSGreedy(js) {
  return typeof js !== 'object' || js === null ? js :
    Array.isArray(js) ?
      Immutable.Seq(js).map(fromJSGreedy).toList() :
      Immutable.Seq(js).map(fromJSGreedy).toMap();
}

console.log(fromJSGreedy(myFoo).toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>

10-02 15:13