2013-12-18 383 views
9

我有問題與JavaScript對象(數組)深拷貝。我讀了很多好方法來處理它。我也知道jQuery有$ .extend API來解決這個問題。但我的問題是:我可以使用JSON stringify和parse方法來解決這個問題嗎?JavaScript深拷貝使用JSON

這裏是我的代碼:

function deepCopy(oldValue) { 
    var newValue 
    strValue = JSON.stringify(oldValue) 
    return newValue = JSON.parse(strValue) 
} 

var a = { 
    b: 'b', 
    c: [1,2,4], 
    d: null 
} 

copy = deepCopy(a) 

console.log(a === copy) // false 
console.log(a.c === copy.c) // false 

PS:我知道,如果沒有所有對象序列化,但我唯一知道的情況是,當對象包含一個屬性,它是功能。任何其他情況?

原諒我可憐的英語,這很好,如果你能指出。

+0

並非所有的對象都可以序列化爲JSON。即使是那些,它似乎不能將它們變成一個字符串,然後解析字符串。但它應該工作得很好。唯一的問題是IE的舊版本,你需要一個polyfill。 –

+0

在這裏檢查http://msdn.microsoft.com/en-us/library/ie/cc836466(v=vs.94).aspx – anand4tech

+0

謝謝!我只知道一個對象不可序列化,如果這個對象包含屬性是一個函數。但是如果其他情況下該對象不可序列化? – user2666750

回答

23

如果您的對象「很小」且包含可排序的屬性,那麼使用JSON序列化的簡單deepCopy應該是可以的。但是,如果你的對象很大,你可能會遇到問題。如果它包含不可序列化的屬性,those'll失蹤:

var o = { 
a: 1, 
b: 2, 
sum: function() { return a + b; } 
}; 

var o2 = JSON.parse(JSON.stringify(o)); 
console.log(o2); 

產量:

Object {a: 1, b: 2} 

有趣的是,相當數量的在C#中的深度拷貝的解決方案是相似的序列化/反序列化的技巧。

附錄:不知道你希望在拷貝後比較對象。但是,對於複雜的物體,您通常需要編寫自己的Compare()和/或Equals()方法以進行精確比較。

還值得注意的是,這種副本不保留類型信息。

JSON.parse(JSON.stringify(new A())) instanceof A === false 
+1

這是在Chrome控制檯中進行快速調試的一個很好的解決方案,因爲Chrome將始終顯示對象的最終狀態,而不是調用console.log函數時的狀態。 –

1

你可以這樣做的,但它的一些上面列出的原因問題:

  1. 我懷疑的性能。

  2. 你有任何不可序列化的屬性?

  3. 而最大的:你的克隆是缺少類型信息。取決於你在做什麼,這可能是重要的。實現者是否將方法添加到原始對象的原型中?那些消失了。我不知道你會失去什麼。