2013-12-18 9 views
9

javascriptオブジェクト(配列)ディープコピーに問題があります。私はそれに対処するために多くの良い方法をお読みください。そして、私はまた、jQueryがこの問題に対する$ .extend APIを持っていることも知っています。しかし、私の質問です:JSON stringifyと解析メソッドを使用してこの問題を解決できますか?ここでJSONを使用したjavascriptディープコピー

は私のコードです:

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としてシリアライズ可能なわけではありません。それらの文字列を文字列に変換して文字列を解析することは非効率的です。しかし、うまくいくはずです。 polyfillが必要な古いバージョンのIEのみが問題です。 –

+0

ここをクリックhttp://msdn.microsoft.com/en-us/library/ie/cc836466(v=vs.94).aspx – anand4tech

+0

ありがとう!このオブジェクトに関数であるプロパティが含まれていると、オブジェクトがシリアライズ可能でないことがわかります。しかし、オブジェクトがシリアライズ可能でない他の状況があれば? – user2666750

答えて

23

オブジェクトが「小さい」もので、排他的にシリアライズ可能なプロパティを含んでいる場合、JSONシリアライズを使用した単純なdeepCopyハックはOKです。しかし、あなたのオブジェクトが大きい場合は、問題に遭遇する可能性があります。それはunserializableプロパティが含まれている場合や、行方不明に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のコンソールでは、console.log関数の呼び出し時の状態ではなく、オブジェクトの最終状態が常に表示されるため、これはChromeのコンソールですばやくデバッグできる便利なソリューションです。 –

1

あなたはそのように行うことができますが、それは上に挙げた理由のいくつかについては問題だ:

  1. 私はパフォーマンスを疑問視。

  2. シリアル化できないプロパティはありますか?

  3. 最大:クローンにタイプ情報がありません。あなたがやっていることに応じて、それは重要なことになるかもしれません。実装者は元のオブジェクトのプロトタイプにメソッドを追加しましたか?それらはなくなった。他に何が失われるのか分かりません。