глубокое копирование javascript с помощью JSON

У меня проблема с глубокой копией объекта javascript(массива). Я читал много хороших способов справиться с этим. И я также знаю, что у jQuery есть $.расширить API для этой проблемы. Но мой вопрос: Могу ли я просто использовать метод JSON stringify и parse для решения этой проблемы?

вот мой код:

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: Я знал, что если нет все объекты сериализуемы, но единственная ситуация, которую я знаю, это когда объект содержит свойство, которое является функцией. Любой другой ситуация?

2 ответов


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

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. Я сомневаюсь в производительности.

  2. У вас есть какие-либо несериализуемых свойства?

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