2016-03-21 82 views
1

使用对象数组时,我对ImmutableJS的功能有点困惑。下面的例子显示,即使List x是不可变的,我仍然可以使用Immutable List的update()函数修改列表中的对象的属性。在ImmutableJS中更新列表中的对象

我的问题是,如果我仍然可以修改我的对象的内容,为什么我会使用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 
@ SpiderPig的使用地图的建议的

https://jsfiddle.net/shotolab/rwh116uw/1/

例子:

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打算让国家变得不可改变,但它并没有被强制执行,在我看来,这样做最终会导致一个混乱,多个开发者。我尽我所能不要改变状态,但忘记修改列表/数组中的对象是非常容易犯的错误。

+1

只有列表本身是不可变的。里面的物体不是。您可以将不可变元素放入列表中,例如使用Immutable.Map而不是普通的JS对象。 – SpiderPig

+0

我添加了一个结合使用Map和List的建议示例。这最终实现了我之后的工作,但是需要一个不同的API来修改Mapped对象,而不仅仅是一个普通的JS对象。 –

回答

2

immutable.js并不提供真正的不可变性,因为您无法直接修改对象 - 它仅提供可帮助您维护不可变状态的API。

更新 - 函数应该返回索引对象的完全新版本:

var y = x.update(0, (element) => { 
    return { name : "bar"}; 
}); 

但是做这样的事情,这是一个很大的禁忌:x.get(0).name = 'baz';

这里的一个更好的解释整个事情比我所能写: https://github.com/facebook/immutable-js/issues/481

immutable.js的要点是允许重复使用对象的哪些不是修改后,消耗更少的内存并提供良好的实际性能。

还有图书馆“无缝不可改变的”,其冻结的对象,使他们不能修改,但这种带有下的JavaScript的性能损失:https://github.com/rtfeldman/seamless-immutable

+0

感谢您提供问题481的链接。并且您的回答证实,至少我遇到的行为是预期的行为。 –