2013-12-18 2 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, где вам нужна полифония. –

+0

проверьте здесь http://msdn.microsoft.com/en-us/library/ie/cc836466(v=vs.94).aspx – anand4tech

+0

Спасибо! Я знаю только, что объект не сериализуем, если этот объект содержит свойство, которое является функцией. Но если в другой ситуации, что объект не сериализуем? – user2666750

ответ

23

Если ваш объект является «маленьким» и содержит исключительно сериализуемые свойства, простой хакерский код deepCopy с использованием сериализации JSON должен быть в порядке. Но, если ваш объект большой, вы можете столкнуться с проблемами. И если он содержит unserializable свойства, those' пропадают:

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# являются подобными трюками сериализации/десериализации.

Addendum: Не уверен, что вы надеетесь в плане сравнения объектов после копии. Но для сложных объектов вам обычно нужно написать свой собственный метод Compare() и/или Equals() для точного сравнения.

Также известно, что такая копия не сохраняет информацию о типе.

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

Это хорошее решение для быстрой отладки в консоли Chrome, так как Chrome всегда отображает конечное состояние объекта, а не то, как оно было, когда вызывалась функция console.log. –

1

Вы можете сделать это таким образом, но это проблематично для некоторых из перечисленных выше причин:

  1. я вопрос производительности.

  2. Есть ли у вас какие-либо свойства, не связанные с сериализацией?

  3. И самое большое: в вашем клоне отсутствует информация о типе. В зависимости от того, что вы делаете, это может быть значительным. Помог ли разработчик добавить методы к прототипу ваших исходных объектов? Те исчезли. Я не уверен, что еще вы проиграете.

Смежные вопросы