var a = {address: {postcode: 5085}}
var b = Immutable.fromJS(a)
var c = b.setIn(['address', 'suburb'], 'broadview').toJS(); // no error
console.log(c);
var d = Immutable.Map(a);
var e = d.setIn(['address', 'suburb'], 'broadview').toJS(); // error invalid keyPath(…)
有人可以解释其中的差异。
谢谢,
答案 0 :(得分:68)
在此示例中,
var a = {address: {postcode: 5085}}
var d = Immutable.Map(a);
此处, d.get('address')
是不可变的。它的值不能改变为任何其他对象。我们只能使用ImmutableJS的Immutable.Map.set()
函数从现有对象创建一个新对象。
但是,d.get('address')
引用的对象,即{postcode:5085}
是一个标准的JavaScript对象。这是可变的。这样的陈述可以改变postcode
:
d.get('address').postcode=6000;
如果再次检查d的值,可以看到他的值已被更改。
console.log(JSON.stringify(d)); //Outputs {"address":{"postcode":6000}}
这违反了不变性原则。
原因是像List
和Map
这样的ImmutableJS数据结构只赋予List
/ Map
的1级成员不变性功能。
所以,如果对象内部有数组或数组内的对象,并且希望它们也是不可变的,那么您的选择是Immutable.fromJS
。
var a = {address: {postcode: 5085}}
var b = Immutable.fromJS(a);
b.get('address').postcode=6000;
console.log(JSON.stringify(b)); //Outputs {"address":{"postcode":5085}}
从上面的例子中你可以清楚地知道fromJS
如何使嵌套成员不可变。
我希望您了解Map
和fromJS
之间的区别。一切顺利=)
答案 1 :(得分:25)
fromJS
进行了深度转换。也就是说,它会遍历所有键并将所有元素转换为列表,地图等。
在第二个示例中,address
是一个普通对象,而不是ImmutableJS对象,因此您无法使用setIn
来更改其值。