2013-12-18 22 views
9

Mam problem z głęboką kopią obiektu javascript (array). Czytałem wiele dobrych sposobów, aby sobie z tym poradzić. Wiem także, że jQuery ma API $ .extend dla tego problemu. Ale moje pytanie brzmi: czy mogę po prostu użyć JSON stringify i parsować metodę, aby rozwiązać ten problem?Głębokie kopiowanie w javascript przy użyciu JSON

Oto mój kod:

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: Znam, że jeśli nie wszystkie obiekty są serializacji, ale sytuacja tylko wiem, że kiedy obiekt zawiera właściwość, która jest funkcją. Każda inna sytuacja?

Przebacz mój biedny angielski, i miło, jeśli możesz to wskazać.

+0

Nie wszystkie obiekty można szeregować jako JSON. Nawet te, które są, wydaje się nieskuteczne, aby przekształcić je w ciąg, a następnie przeanalizować ciąg. Ale powinno działać dobrze. Jedynym problemem są stare wersje IE, w których potrzebujesz polyfill. –

+0

sprawdź tutaj http://msdn.microsoft.com/en-us/library/ie/cc836466(v=vs.94).aspx – anand4tech

+0

Dzięki! Wiem tylko, że obiekt nie podlega serializacji, jeśli ten obiekt zawiera właściwość, która jest funkcją. Ale czy w innej sytuacji obiekt nie nadaje się do serializacji? – user2666750

Odpowiedz

23

Jeśli twój obiekt jest "mały" i zawiera wyłącznie serializowalne właściwości, prosty hackowanie przy użyciu serializacji JSON powinno być w porządku. Ale jeśli twój obiekt jest duży, możesz napotkać problemy. A jeżeli zawiera on właściwości unserializable, those'll iść brakuje:

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

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

Wynik:

Object {a: 1, b: 2} 

Co ciekawe, spora liczba rozwiązań głębokie kopiowanie w C# są podobne sztuczki serializacji/deserializacjia.

Dodatek: Nie masz pewności, na co masz nadzieję pod względem porównywania obiektów po skopiowaniu. Ale w przypadku obiektów złożonych, zazwyczaj trzeba napisać własną metodę Compare() i/lub Equals() dla dokładnego porównania.

Co więcej, ten rodzaj kopii nie zachowuje informacji o typie.

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

To dobre rozwiązanie do szybkiego debugowania w konsoli Chrome, ponieważ Chrome zawsze wyświetla ostateczny stan obiektu, zamiast tego, jak to się stało, gdy wywołano funkcję console.log. –

1

Można zrobić to w ten sposób, ale jest to problem dla niektórych z wyżej wymienionych powodów:

  1. mam pytanie wydajności.

  2. Czy posiadasz jakieś niezdatne do sfotografowania właściwości?

  3. A największy: Twój klon nie zawiera informacji o typie. W zależności od tego, co robisz, może to być znaczące. Czy osoba wdrażająca dodała metody do prototypu oryginalnych obiektów? Te już nie ma. Nie jestem pewien, co jeszcze stracisz.

Powiązane problemy