ホームページ > 記事 > ウェブフロントエンド > JavaScript のオブジェクト コピー メソッドの詳細な分析 (コード付き)
前回の記事「JavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)」では、JavaScript「jquery継承」の使い方について学びました。以下の記事ではJSでオブジェクトをコピーする方法を紹介していますので、困っている方は参考にしてみてください。
javascript
でオブジェクトをコピーする場合、最初に思い浮かぶのは Object.assign()## です。
#JSON.parse(JSON.stringify())、および
ES6 の展開演算子 [
...]
js#=
では、operator はオブジェクトのコピーを作成できないため、これはオブジェクトへの参照にすぎませんOperator
var x = { a: 1, b: 2, }; y = x; x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:10, b:2}
) は推奨されません
var x = { a: 1, b: 2, }; y = Object.assign({}, x); x.a = 10; console.log(x); //{a:10, b:2} console.log(y); //{a:1, b:2}一見すると、次のようになります。ではありません 欲しいものは欲しい結果なので例外が見つかります オブジェクトの構造をもう少し複雑にして見てみると
var x = { a: 1, b: 2, c: { d: 3, }, }; y = Object.assign({}, x); x.a = 5; console.log(x); //{a:5, b:2, c:{d:3}} console.log(y); //{a:5, b:2, c:{d:3}} x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:5, b:2, c:{d:10}}
ですが、この時に落とし穴が見つかります。それは証明されています
Object.assign()オブジェクトの浅いコピーのみを実装します
もう 1 つ注意すべきことは、列挙不可能であることです。プロトタイプ チェーンに属性を持つオブジェクトはコピーできません。コードを見てください。 : <pre class="brush:php;toolbar:false">var x = {
a: 1,
};
var y = Object.create(x, {
b: {
value: 2,
},
c: {
value: 3,
enumerable: true,
},
});
var z = Object.assign({}, y);
console.log(z); //{c:3}</pre>
が
の値を取得するのは驚くべきことです。なぜなら x
はy
のプロトタイプ チェーンであるため、#xx はコピーされません
属性
b
c
上記の落とし穴も非常にうまく解決でき、以下のようになります。深いコピー
JSON.parse(JSON.stringify())
var x = { a: 1, b: 2, c: { d: 3, }, }; y = JSON.parse(JSON.stringify(x)); x.a = 5; x.c.d = 10; console.log(x); //{a:5, b:2, c:{d:10}} console.log(y); //{a:1, b:2, c:{d:3}}
もちろん、通常のオブジェクトの場合、このコピー方法は基本的には完璧なので、落とし穴はどこにありますか
var x = { a: 1, b: function b() { return "2"; }, }; y = JSON.parse(JSON.stringify(x)); z = Object.assign({}, x); console.log(y); //{a:1} console.log(z); //{a:1, b:function b(){return '2'}}
Object.assign()
はメソッドJSON.parse(JSON.stringify())
をコピーできます。 cannot 2 つ目の落とし穴を見てみましょう。落とし穴:
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = JSON.parse(JSON.stringify(x)); console.log(x); /* Uncaught TypeError: Converting circular structure to JSON at JSON.stringify (<anonymous>) at <anonymous>:8:25 */
がエラーを報告し、結果は
JSON.parse(JSON.stringify()),cannot を示しています。循環参照オブジェクトをコピーします見てみましょう Object.assign()
var x = { a: 1, b: { c: 2, d: 3, }, }; x.c = x.b; x.d = x.a; x.b.c = x.c; x.b.d = x.d; var y = Object.assign({}, x); console.log(x); /* [object Object]{ a:1, b:[object, Object], d:[object, Object], d:1 } */展開演算子を使用します [
... ]
var x = [ "a", "b", "c", "d", { e: 1, }, ]; var y = [...x]; console.log(y); //['a', 'b', 'c', 'd', {'e':1}] var m = { a: 1, b: 2, c: ["d", "e"], }; var n = { ...m, }; console.log(n); //{a:1, b:2, c:['d', 'e']}
自分の車輪を発明する:
function copy(x) { var y = {}; for (m in x) { y[m] = x[m]; } return y; } var o = { a: 1, b: 2, c: { d: 3, e: 4, }, }; var p = copy(o);これを実行しても大きな問題はないはずだと言う人もいます。
var x = {}; Object.defineProperty(x, "m", { value: 5, writable: false, }); console.log(x.m); //5 x.m = 25; //这一步没报错,但是也没执行 console.log(x.m); //5このように、展開演算子はここでオブジェクトをコピーするときに落とし穴に遭遇することになります。 落とし穴はどこにでもあり、それらを防ぐのは困難です。これを書いている時点で、完全にはリストされていない落とし穴がまだたくさんあると思います。I'詳細は後ほど書きます
##[終了]
推奨学習:
JavaScript ビデオ チュートリアル以上がJavaScript のオブジェクト コピー メソッドの詳細な分析 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。