js deep copy, shallow copy

Shallow copy

For basic types, a shallow copy is the copy of the value of the object, the shallow copy copy only a pointer to an object, rather than copying the object itself, and not open up a new stack, which is the result of old and new object or copy share the same memory, two objects point to the same address, modify the properties of an object, the other attributes of the object will change.

Deep copy

Deep copy will open up a new stack, create an identical objects, two objects correspond to two different addresses, do not share memory, modify the properties of an object, does not change the properties of another object.

The basic types and object type
their biggest difference is that they pass by value. The basic type is the object type by value is passed by reference.

<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>

Here a copy of obj is called obj2, where b is the modified obj2 3,647,367 also modify the obj1.b. Because they always been an object This is called a shallow copy.
To avoid such a situation we write

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}

This is a deep copy will not change to the original obj1.

  • Shallow copy copy only a pointer to an object, rather than copying the object itself, or the old and new objects share the same memory. But deep copy would otherwise create an identical objects, the new object with the original object is not shared memory, modify the new object is not to change the original object.

    How to do a deep copy
    To complete copy can not modify the original object, this time we should use a deep copy, here is a deep copy in several ways:
  • 1, to manually copy the
    example as above, the property of one copy of obj1 to obj2 in:
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}

But this is very troublesome to replicate themselves slowly, but this is actually not a deep copy, if something like this situation.

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

Although obj1 obj2 with different objects, but they will share the same obj1.body, it will also modify the old time to modify obj2.body.a.

    1. Object.assign
      Object.assign ES6 is a new function that can help us achieve the same with the above functions.
    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) meant to create an empty object {}, then obj1 all the attributes copied in the past, so the president takes as obj2 obj1, this time to modify obj2.b will not affect obj1. Because Object.assign same effect with our copy of the manual, as it can handle only one level deep objects , no way to be truly deep copy, but if the object you want to copy only one layer, then you can consider using it.
When the following nested objects, there is no way to do a deep copy:

    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, turn to turn back JSON
    with JSON.stringify the object into a string, the string JSON.parse then transformed into a new object.
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

This is true Deep Copy, but only can be converted into an object in JSON format so it can be used as function can not turn into 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' <-- 没复制

To copy function will directly disappear, so this method can only be used in simple objects and only data.

  • 4, jQuery's $ .extend

jquery has provided a $ .extend can be used to make a deep copy:

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, lodash of _.cloneDeep
library lodash provide _.cloneDeep used to make a deep copy:

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

This is the recommended way to compare the performance is also good, very simple to use.

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

Guess you like

Origin www.cnblogs.com/jessie-xian/p/11596081.html