2017-06-21 76 views
5

我想深入克隆一個對象,用k = JSON.parse(JSON.stringify(a))說「a」。我使用stringify方式很重要,因爲我試圖將對象保存到文件中,然後從中加載。javaScript:使用JSON.parse解析字符串化對象,刪除引用

我偶然發現與克隆的對象上的引用中的問題,其如下所示:

var obj={}; 
 
obj.importantProperty={s:2}; 
 
obj.c=obj.importantProperty; 
 
obj.d=obj.importantProperty; 
 
console.log(obj.c === obj.d); // Returns true 
 

 
var cloned = JSON.parse(JSON.stringify(obj)); 
 
console.log(cloned.c === cloned.d); // Returns false
我需要保持的參考文獻中使用JSON.parse時,在上面的例子中它們是不。在我的項目中,對象更加複雜,但最終歸結於上面的示例。

在此先感謝任何人誰幫助我這個:)

+3

'JSON.parse'創建一個從字符串表示一個新的結構。無法理解兩個對象是相同的。 –

+0

甚至更​​多:'克隆=== obj - > false'。 –

+0

克隆=== obj - > false是正常的,因爲克隆的對象是深克隆,即不同的引用。感謝您的回覆。 –

回答

0

做這樣的事情的正確方法是分別存儲通用的引用對象並通過ID引用它。

舉例來說,你可以在一個陣列握住你的importantProperty對象,並使用指數作爲ID:

var importantProperties = [ 
    { s: 1 }, 
    { s: 2 }, 
    { s: 3 } 
]; 

var obj = {}; 
obj.importantProperty = importantProperties[1]; 
obj.c = obj.importantProperty; 
obj.d = obj.importantProperty; 

然後,當你字符串化的對象,你替換它的索引被引用的對象:

var stringified = JSON.stringify(obj, function(key, value) { 
    if (key) { 
    return importantProperties.indexOf(value); 
    } 
    return value; 
}); 
console.log(stringified); 
// prints {"importantProperty":1,"c":1,"d":1} 

然後當你分析你根本扭轉這一進程,重振引用:

var parsed = JSON.parse(stringified, function(key, value) { 
    if (key) { 
    return importantProperties[value]; 
    } 
    return value; 
}); 
console.log(parsed.c === parsed.d && parsed.d === parsed.importantProperty); 
// prints true 

現在,上面的示例適用於您的示例代碼,前提是obj中的所有屬性都是importantProperties數組中的對象。如果情況並非如此,並且只有某些屬性是importantProperties對象,則需要在更換/恢復時檢查該對象。
假設只有「importantProperty」,「c」和「d」的屬性是這樣的對象:
​​,而不是僅僅if (key)

如果這還不夠好,你不想要的屬性名稱有無論該值是否爲importantProperties對象,您都需要在標識符中指定該值。這裏有一個如何可以做到這一點的例子:

// Replacing 
JSON.stringify(obj, function(k, value) { 
    if (importantProperties.includes(value)) { 
    return 'ImportantProperty[' 
     + importantProperties.indexOf(value) 
     + ']'; 
    } 
    return value; 
}); 

// Reviving 
JSON.parse(stringified, function(k, value) { 
    if (/^ImportantProperty\[\d+\]$/.test(value)) { 
    var index = Number(value.match(/\d+/)[0]); 
    return importantProperties[index]; 
    } 
    return value; 
}); 
0

這是不可能實現的使用JSON你想要的結果,因爲JSON格式可以只包含數據類型的有限ammount的(http://json.org/),當你的字符串化對象到JSON一些信息會丟失。

也許還有一些其他類型的序列化技術,但我會建議您尋找另一種方法來存儲數據。