2015-10-23 77 views
27
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(…) 

有人可以解釋這種差異。ImmutableJS Map()和fromJS()有什麼區別?

感謝,

回答

24

fromJS做了深度轉化。也就是說,它會通過遞歸所有的按鍵和所有元素轉換成列表,地圖等

在你的第二個例子,address是一個普通的對象,而不是一個ImmutableJS對象,所以你不能使用setIn改變其值。

49

在這個例子中,

var a = {address: {postcode: 5085}} 
var d = Immutable.Map(a); 

這裏,d.get('address')是不可改變。它的價值無法改變爲任何其他物件。我們只能使用ImmutableJS的Immutable.Map.set()函數從現有對象創建一個新對象。

但是,由d.get('address')引用的對象,即{postcode:5085}是標準的JavaScript對象。這是可變的。如果檢查的值D再次,你可以看到他的值已經改變

d.get('address').postcode=6000; 

:像這樣的語句可以改變的postcode值。

console.log(JSON.stringify(d)); //Outputs {"address":{"postcode":6000}} 

這是違反不變性的原則。

其原因是,像ListMap 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使得嵌套的成員不變。

我希望你能明白MapfromJS之間的區別。所有最好=)

+1

omg,非常感謝你解釋這個!我一直在努力,我終於明白爲什麼我的map.get(k)是通過引用返回的(以及如何避免它沒有做一些愚蠢的deepCopy(map.get(k)) – grendian

+0

優秀! Immutable.js Map docs並不清楚這個來自JS的核心差異:https://facebook.github.io/immutable-js/docs/#/Map –