Detailed Explanation of javascript Deep Copy and Shallow Copy

  • 2021-07-21 06:44:34
  • OfStack

1. Deep and shallow copies of arrays

When using JavaScript to operate on arrays, we often need to back up arrays. Facts have proved that if we simply assign it to other variables, we only need to change any one of them, and then the others will change accordingly, which leads to problems.

Why is this?

Because if it is a simple assignment, it only refers to the address, so changing one will change the other.


var arr = ["One","Two","Three"];
var arrto = arr;
arrto[1] = "test";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,test,Three
document.writeln(" The new value of the array: " + arrto + "<br />");//Export: The new value of the array: One,test,Three

Like the above, it belongs to shallow copy, so how can we not change the original?

Method 1: slice function of js


var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtoo + "<br />");//Export: The new value of the array: One,set Map,Three

Method 2: concat method of js

The concat () method is used to concatenate two or more arrays.

This method does not change the existing array, but only returns 1 copy of the connected array.


var arr = ["One","Two","Three"];
var arrtooo = arr.concat();
arrtooo[1] = "set Map To";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtooo + "<br />");//Export: The new value of the array: One,set Map To,Three

2. Deep and shallow copies of objects


var a={name:'yy',age:26};
var b=new Object();
b.name=a.name;
b.age=a.age;
a.name='xx';
console.log(b);//Object { name="yy", age=26}
console.log(a);//Object { name="xx", age=26}

Or


var deepCopy= function(source) {
 var result={};
 for (var key in source) {
  result[key] = typeof source[key]==='object'? deepCoyp(source[key]): source[key];
 } 
 return result; 
}

object () method: Douglas Crockford, the inventor of json format, proposed an object () function, which can do this.


function object(o) {
          function F() {}
          F.prototype = o;
          return new F();
    }
// This object() Function, in fact, only does 1 One thing, is to put the child object's prototype Property, pointing to the parent object, so that the child object is connected to the parent object in the 1 Get up. 

When using, the first step is to generate child objects based on the parent object:


var Doctor = object(Chinese);
// Then, add the attributes of the child object itself: 
Doctor.career = ' Doctor ';
// At this time, the child object has inherited the attributes of the parent object. 
alert(Doctor.nation); // China 

Let's take a look at Ruan 1feng's method

For example, there is now an object called "Chinese".


    var Chinese = {
          nation:' China '
    };

There is also an object called "doctor".


    var Doctor ={
          career:' Doctor '
    }

How can I let "doctors" inherit "Chinese people", that is to say, how can I generate an object of "Chinese doctors"?

3. Shallow copy

In addition to using "prototype chain", there is another idea: copying all the attributes of the parent object to the child object can also realize inheritance.

The following function is copying:


    function extendCopy(p) {
          var c = {};
          for (var i in p) { 
                c[i] = p[i];
          }
          c.uber = p;
          return c;
    }

When using it, write:


var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtoo + "<br />");//Export: The new value of the array: One,set Map,Three
0

However, there is one problem with such copies. That is, if the attribute of the parent object is equal to an array or another object, in fact, the child object only gets a memory address, not a real copy, so there is the possibility that the parent object may be tampered with.

See, now add a "birthplace" attribute to Chinese, whose value is an array.

   Chinese.birthPlaces = ['北京','上海','香港'];

Through the extendCopy () function, Doctor inherits Chinese.

   var Doctor = extendCopy(Chinese);

Then, we add a city to the "birthplace" of Doctor:

   Doctor.birthPlaces.push('厦门');

What happened? The "birthplace" of Chinese has also been changed!   


var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtoo + "<br />");//Export: The new value of the array: One,set Map,Three
1

Therefore, extendCopy () only copies the basic type of data, which we call "shallow copy". This is how inheritance was implemented in the early jQuery.

4. Deep copy

The so-called "deep copy" is to realize the copy of arrays and objects in the true sense. Its implementation is not difficult, just call "shallow copy" recursively.


var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtoo + "<br />");//Export: The new value of the array: One,set Map,Three
2

Write this when using:

var Doctor = deepCopy(Chinese);

Now, add an attribute to the parent object, and the value is an array. Then, modify this property on the child object:


    Chinese.birthPlaces = [' Beijing ',' Shanghai ',' Hong Kong '];
    Doctor.birthPlaces.push(' Xiamen ');

At this time, the parent object will not be affected.


var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln(" The original value of the array: " + arr + "<br />");//Export: The original value of the array: One,Two,Three
document.writeln(" The new value of the array: " + arrtoo + "<br />");//Export: The new value of the array: One,set Map,Three
4

At present, jQuery library uses this inheritance method.


Related articles: