【问题标题】:Why is it possible to mutate the value of an item in an Immutable.List?为什么可以改变 Immutable.List 中项目的值?
【发布时间】:2021-07-22 13:16:30
【问题描述】:

Immutable.List 似乎不会阻止您将其视为可变数组:

const Immutable =require( 'immutable');
const l = Immutable.List([1,2,3,4,5]);
l[4] = 9;

console.log(l[4], l.get(4)) // outputs 9, 5

Runkit

这似乎令人惊讶,并且似乎没有在文档中解决。

我在这里误解了什么?我曾想象 Immutable.JS 以某种方式保护您免受变异的影响,但我认为它需要您坚持定义的 API 才能获得这些好处?

【问题讨论】:

  • 我不使用 Immutable,但您在这里所做的是向返回的对象添加属性 4。你能不能试试Object.freeze(l),。是的,我假设你需要做l.get().. Immutable 不太可能返回一个数组,据我记得在 Javascript 中扩展 Array 类型有一些历史问题。
  • 哦...我没想到。您可以在任何对象上执行 x[4]=9,即使是不是数组的对象,嗯。随时将您的评论作为答案。

标签: javascript immutability immutable.js


【解决方案1】:

您可以尝试查看列表的属性以了解发生了什么:

您的代码所做的不是修改索引 4 处的项目,而是向对象添加一个带有键“4”的新属性。

【讨论】:

    【解决方案2】:

    看起来 Immutable 在内部处理了不可变性。如果您在代码末尾记录列表本身,它会显示

    List {
      '4': 9,
      size: 5,
      _origin: 0,
      _capacity: 5,
      _level: 5,
      _root: null,
      _tail: VNode { array: [ 1, 2, 3, 4, 5 ], ownerID: undefined },
      __ownerID: undefined,
      __hash: undefined,
      __altered: false
    }
    

    所以当您使用l[4] = 9 时,实际上是在向列表object 添加一个新属性,而不是列表的内部表示。

    如果你使用

    Object.freeze(l)
    

    在调用之前,然后它可以正常工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-03
      相关资源
      最近更新 更多