JSディープコピー、シャローコピー

シャローコピー

基本的なタイプでは、浅いコピーは、オブジェクトの値のコピー、唯一のオブジェクトへのポインタではなく、オブジェクト自体をコピー浅いコピーのコピーで、古いものと新しいオブジェクトやコピーの結果である新しいスタックを、開いていません同じメモリを共有する、2つのオブジェクトが同一のアドレスを指し、オブジェクトのプロパティを変更し、オブジェクトの他の属性が変更されます。

ディープコピー

ディープコピーは、新しいスタックを開き、同一のオブジェクトを作成し、2つのオブジェクトが2つの異なるアドレスに対応し、メモリを共有しない、オブジェクトのプロパティを変更し、別のオブジェクトのプロパティを変更しないでしょう。

基本タイプとオブジェクトが入力
彼らの最大の違いは、彼らが値渡しということです。基本的なタイプは、参照によって渡された値によってオブジェクト・タイプです。

<script>
    var a = 100;
    var b = a;
    b = 200;
    console.log(a);   //100
    console.log(b);   //200
    //修改a的时候,b不会改变
   //基本类型是按值传递,像是这样:在修改a时并不会改到b

    var obj1 = {
        a:100,
        b:200,
        c:300
    }
    var obj2 = obj1;
    obj2.b = 3647367;  //修改b
    console.log(obj1);   //{a: 100, b: 3647367, c: 300}
    console.log(obj2);   //{a: 100, b: 3647367, c: 300}
    //但对象就不同,对象传的是按引用传值
    //因为他们根本是同一个对象,这就是所谓的浅拷贝。
</script>

ここではOBJのコピーは、bは3647367もobj1.b.を変更obj2が変更されOBJ2、と呼ばれています 彼らは常に、対象となっているのでこれは浅いコピーと呼ばれています。
私たちが書くような事態を回避するために、

var obj1 = {
        a: 100,
        b: 200,
        c: 300
    }
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }
    obj2.b = 3647367;  //修改b
    console.log(obj1);   //{a: 100, b: 200, c: 300}
    console.log(obj2);   //{a: 100, b: 3647367, c: 300}

これは、元のOBJ1に変更されることはありませんディープコピーです。

  • 浅いコピーのコピーのみオブジェクトへのポインタではなく、オブジェクト自体のコピー、または古いものと新しいオブジェクトが同じメモリを共有しています。しかし、ディープコピーがそれ以外は同一のオブジェクトを作成し、元のオブジェクトを持つ新しいオブジェクトが新しいオブジェクトは元のオブジェクトを変更しないで修正し、メモリを共有されません。

    深いコピーを実行する方法
    コピーは元のオブジェクトを変更することはできません完了するために、我々は深いコピーを使用する必要があり、この時は、ここに深いコピーは、いくつかの方法であります:
  • 図1に示すように、手動でコピーするために
    、上記のようにOBJ2するOBJ1の一つのコピーのプロパティの例:
var obj1 = {
        a: 100,
        b: 200,
        c: 300
    }
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }
    obj2.b = 3647367;  //修改b
    console.log(obj1);   //{a: 100, b: 200, c: 300}
    console.log(obj2);   //{a: 100, b: 3647367, c: 300}

しかし、これはゆっくりと自分自身を複製することは非常に面倒ですが、このような状況のようなものならば、これは、実際には深いコピーではありません。

var obj1 = { body: { a: 10 } };
var obj2 = { body: obj1.body }; 
obj2.body.a = 20;
console.log(obj1);     // { body: { a: 20 } } <-- 被改到了
console.log(obj2);     // { body: { a: 20 } }
console.log(obj1 === obj2);      // false
console.log(obj1.body === obj2.body);    // true

彼らは同じobj1.bodyを共有する別のオブジェクトとのOBJ1 OBJ2が、しかし、それはまた、obj2.body.a.を修正するために、古い時間を変更します

    1. Object.assign
      Object.assign ES6は、私たちは上記の機能と同じことを達成するのを助けることができる新しい機能です。
    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = Object.assign({}, obj1);
    obj2.b = 100;
    console.log(obj1);    // { a: 10, b: 20, c: 30 } <-- 沒被改到
    console.log(obj2);   // { a: 10, b: 100, c: 30 }

Object.assignは({}、OBJ1)すべての属性が過去にコピーしたOBJ1、その後、空のオブジェクト{}を作成するためのものなので、社長がobj2はOBJ1として受け取り、obj2.bを変更するには、この時間は影響しませんOBJ1。マニュアルの私達のコピーとObject.assign同じ効果は、それが通りますので一つだけレベルの深さのオブジェクトを扱うことができ、方法は本当に深いコピーがないように、そのオブジェクトは、あなたが一層のみをコピーしたい場合は、その後、あなたはそれを使用することを検討することができます。
ネストされたオブジェクト以下の場合には、深いコピーを実行する方法はありません。

    var obj1 = { a: 0 , b: { c: 0}};
    var obj2 = Object.assign({}, obj1);
    console.log(obj2); // { a: 0, b: { c: 0}}

    obj1.a = 1;
    console.log(obj1);  // { a: 1, b: { c: 0}}
    console.log(obj2);   // { a: 0, b: { c: 0}}

    obj2.a = 2;
    console.log(obj1);    // { a: 1, b: { c: 0}}
    console.log(obj2);    // { a: 2, b: { c: 0}}

    obj2.b.c = 3;
    console.log(obj1);    // { a: 1, b: { c: 3}}
    console.log(obj2);    // { a: 2, b: { c: 3}}
  • 3、JSONを元に戻すために回し
    文字列にJSON.stringifyを持つオブジェクトを、文字列JSON.parseは、新しいオブジェクトに変換します。
var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1)); 
obj2.body.a = 20;
console.log(obj1);    // { body: { a: 10 } } <-- 沒被改到
console.log(obj2);    // { body: { a: 20 } }
console.log(obj1 === obj2);     // false
console.log(obj1.body === obj2.body);      // false

これが本当のディープコピーであるが、それは関数として使用できるようにだけJSONに変えることができないJSON形式のオブジェクトに変換することができます。

var obj1 = { fun: function(){ console.log(123) } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(typeof obj1.fun);  // 'function'
console.log(typeof obj2.fun);  // 'undefined' <-- 没复制

機能をコピーするには直接表示されなくなりますので、この方法は、単純なオブジェクトとデータのみで使用することができます。

  • 4、jQueryの$ .extend

jqueryのは、$ .extendは深いコピーを作成するために使用することができます提供してきました。

var $ = require('jquery');
var obj1 = {    a: 1,    b: { f: { g: 1 } },    c: [1, 2, 3] };
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);  // false

5、_.cloneDeepののlodash
_.cloneDeepは深いコピーを作成するために使用提供lodashライブラリ:

var _ = require('lodash');
var obj1 = {    a: 1,    b: { f: { g: 1 } },    c: [1, 2, 3] };
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);     // false

これは、性能を比較するための推奨方法ですまた、使用することは非常に簡単で、良いです。

参考:https://www.cnblogs.com/lmjZone/p/8521443.html
https://www.cnblogs.com/syomm/p/5903740.html

おすすめ

転載: www.cnblogs.com/jessie-xian/p/11596081.html