Javascript 为什么可以在不可变的.List中改变项的值?

Javascript 为什么可以在不可变的.List中改变项的值?,javascript,immutability,immutable.js,Javascript,Immutability,Immutable.js,不可变。列表似乎不会阻止您将其视为可变数组: 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 这似乎令人惊讶,文档中似乎没有提到 我在这里误解了什么?我原以为Immutable.JS会以某种方式保护您,使您不受变异的影响,但我认为它要求您坚持使用已定义的API来获得这些好处?

不可变。列表似乎不会阻止您将其视为可变数组:

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

这似乎令人惊讶,文档中似乎没有提到


我在这里误解了什么?我原以为Immutable.JS会以某种方式保护您,使您不受变异的影响,但我认为它要求您坚持使用已定义的API来获得这些好处?

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


您的代码所做的不是修改索引4中的项,而是向对象添加键为“4”的新属性。

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


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

似乎不可变在内部处理不可变性。如果在代码末尾记录列表本身,它将显示

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.freeze(l)

在调用之前,它会正常工作

似乎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.freeze(l)

在调用之前,它会正常工作

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