在处理一组对象时,我对ImmutableJS的功能感到有些困惑。下面的例子表明,即使List x是不可变的,我仍然可以使用和不使用Immutable List的update()函数来修改列表中对象的属性。
我的问题是,如果我仍然可以修改对象的内容,为什么我会使用Immutable?我希望这个模块能够保护我。我意识到我将无法在列表中添加或删除整个对象,但这并不能完全保护我不修改列表,当使用React状态的列表时,我不希望能够要做。
我注意到的另一个有趣的事情是,当我在第一次执行更新后直接修改名称时,x.get(0).name和y.get(0).name都被更改。我认为update()的结果列表不会包含对列表中相同对象的引用。
在这种情况下,ImmutableJS如何以及为何真正帮助我?
var x = Immutable.List.of({name: 'foo'});
console.log(x.get(0).name);
var y = x.update(0, (element) => {
element.name = 'bar';
return element;
});
console.log(x.get(0).name);
console.log(y.get(0).name);
x.get(0).name = 'baz';
console.log(x.get(0).name);
console.log(y.get(0).name);
Output:
foo
bar
bar
baz
baz
https://jsfiddle.net/shotolab/rwh116uw/1/
@ SpiderPig建议使用Map的例子:
var x = Immutable.List.of(new Immutable.Map({name: 'foo'}));
console.log(x.get(0).get('name'));
var y = x.update(0, (element) => {
return element.set('name', 'bar');
});
console.log(x.get(0).get('name'));
console.log(y.get(0).get('name'));
Output:
foo
foo
bar
虽然最后一个例子显示了我想要完成的事情,但最终我不知道我是否最终会使用Map或List甚至ImmutableJS。我不喜欢的是替代API(特别是对于映射对象)。我担心当我将项目交给另一个开发人员,或者当其他人加入团队时,如果没有适当的治理,正确使用这些不可变对象和列表将完全崩溃。
也许这更像是对React的评论,但是如果React打算将状态变为不可变,但是它没有强制执行,那么在我看来这样的事情就会在一个快速移动的项目中变得一团糟开发人员。我正在尽力不改变状态,但忘记修改列表/数组中的对象很容易犯错。
答案 0 :(得分:2)
在你无法直接修改对象的意义上,immutable.js不提供真正的不变性 - 它只提供API来帮助你维护不可变状态。
update -function应该返回索引对象的全新版本:
var y = x.update(0, (element) => {
return { name : "bar"};
});
但做这样的事情是一个很大的禁忌:x.get(0).name = 'baz';
这是一个比我写的更好的解释整个事情: https://github.com/facebook/immutable-js/issues/481
immutable.js 的目的是允许重复使用未修改的对象,这会消耗更少的内存并提供良好的实际性能。
还有库" Seamless immutable",它冻结了对象,因此它们无法修改,但这会在JavaScript下带来一些性能损失:https://github.com/rtfeldman/seamless-immutable