This article will show you the basics of JavaScript: deep copy and shallow copy

This article will show you the basics of JavaScript: deep copy and shallow copy

Copy (also known as clone, duplicate, etc.), but it is divided into deep copy and shallow copy.

In fact, this problem is sometimes very simple if you figure it out. If you don’t figure it out, it may be a bit confusing, but it is much easier to understand than closures.

Why does this concept exist? Let me give you an example.

var person = {
    name:"Zhang San",
    age:22
}
var person1=person;
console.log(person);
console.log(person1);

insert image description here

It seems that it can be copied, but if you operate the attribute value of person1, the attribute value of person will also change.

person1.name="Li Si";
console.log(person);
console.log(person1);

insert image description here

In fact, this is very easy to understand. That is, the pointer addresses of the two objects above point to the same location in the stack memory. When explaining the reference data type earlier, we explained what the reference data type is.

Replenish:

Object.property and object[property] are actually both attribute values ​​of the operation object, just two different ways of writing.

That means this way of assigning pointers is not copying. Then what is copying? It means that a new object uses all the properties of an object, but they are not affected by each other.

With this understanding, we can understand that the essence of copying is to cyclically assign the properties of an object to a new object.

Then why are there shallow copies and deep copies? To be honest, is there any essential difference between shallow copies and deep copies?

In fact, there is no essential difference. The biggest difference is the conditions considered and the attribute types in the copying process.

As usual, look at the code first

Shallow copy

var person = {
    name:"Zhang San",
    age:22
}
var person1={};
for( key in person){
    console.log(key);
    person1[key]=person[key];
}
console.log(person);
console.log(person1);

insert image description here

person1.name="Li Si";
console.log(person);
console.log(person1);

insert image description here

It can be seen that there is no impact on each other, but a new problem will be involved, that is, the attributes of the person object are all basic data types, what if they are reference types? For example, arrays, objects?

var person = {
    name:"Zhang San",
    age:22,
    son:
        firstSon:"Zhang Damao"
    }
}
var person1={};
for( key in person){
    console.log(key);
    person1[key]=person[key];
}
console.log(person);
console.log(person1);

insert image description here

Now modify the send attribute of person1.

person1.son={firstSon:"Li Damao"};
console.log(person);
console.log(person1);

insert image description here

Doesn't it seem like they don't affect each other? But as mentioned before, object.property = is equivalent to rewriting and assigning the property of person1.son, which will naturally disconnect the influence of each other's references, after all, the two addresses are different. But what about the following modifications?

person1.son.secondeSon="Li Damao";
console.log(person);
console.log(person1);

insert image description here

Surprising or not, unexpected or not, they still affect each other. At this time, a new operation is needed, that is, deep copy. To put it simply, the attribute value may be changed to a reference type.

Replenish:

If there are attribute values ​​on the prototype of person, they will also be retrieved by person1 and assigned to person1. This has been mentioned before. In that case, hasOwnProperty will be used to determine whether it belongs to one's own attribute value.

Deep Copy

In fact, the difference between deep copy and shallow copy, I believe you have almost understood it by now, it’s just a matter of considering the type of attribute value.

// As mentioned above, the values ​​on the prototype will also be copied. For convenience, the prototype chain of the object is directly used and the properties are added to the Object at the end.
Object.prototype.address="Guess";
var person = {
    name:"Zhang San",
    age:22,
    son:
        firstSon:"Zhang Damao"
    }
}
strtype=Object.prototype.toString;
var person1={};
// For convenience, use the recursive method here function coleFun(origin,target){
 // Prevent the target object from having attributes target=target||{}
    for(key in origin){
        if (origin.hasOwnProperty(key)) 
         if(strtype.call(origin[key])=="[object Object]"){
            target[key]={};
            target[key]=coleFun(origin[key],target[key])
         }else{
            target[key]=origin[key];
          }   
    }
    return target;
}
person1=coleFun(person,person1)
console.log(person);
console.log(person1);

insert image description here

See the result, there is no problem, try to modify the attribute value

person1.son.secondeSon="Li Damao";
console.log(person);
console.log(person1);

insert image description here

It seems that there is no problem now.

The so-called deep and shallow copy, to put it simply, is to consider whether the attribute value has a reference type and then copy it. If you don’t understand the above code, you may need to review the difference between reference data and basic data, what this points to, and how to determine the data type. This has been discussed in previous articles, you can take a look.

Replenish

A friend asked in the comment section if we use the JSON method in JavaScript to copy data, is it a deep copy or a shallow copy?

In fact, this is very easy to prove. Just copy an object with a reference data type and then determine whether they will affect each other.

First, let’s look at the two methods and their functions:

method effect
JSON.parse() Used to convert a JSON string to a JavaScript object.
JSON.stringify() Used to convert a JavaScript value to a JSON string.

Then the code demonstrates:

var person = {
    name:"Zhang San",
    age:22,
    son:
        firstSon:"Zhang Damao"
    }
}
var str = JSON.stringify(person);
var person1 = JSON.parse(str);
console.log(person);
console.log(person1);

insert image description here

At least the copied results seem to be OK.

Now start testing whether they affect each other

person1.son.secondeSon="Li Damao";
console.log(person);
console.log(person1);

insert image description here

It can be seen that there is no mutual influence. Copying through JOSN is actually a common way of JavaScript. After all, it is much more convenient than writing it yourself. Its essence is to convert the object into a string in JSON format, and then generate an object through the string, so it is also a deep copy.

Summarize

This article ends here. I hope it can be helpful to you. I also hope you can pay more attention to more content on 123WORDPRESS.COM!

You may also be interested in:
  • A brief discussion on JavaScript shallow copy and deep copy
  • Detailed description of shallow copy and deep copy in js
  • Detailed explanation of JS deep copy and shallow copy
  • Analysis of JS's method of implementing deep copy of arrays
  • Summary of several situations of javascript deep copy

<<:  Specific usage of textarea's disabled and readonly attributes

>>:  Analysis and solution of the reasons for left and right jumps when loading web pages

Recommend

Docker installs Redis and introduces the visual client for operation

1 Introduction Redis is a high-performance NoSQL ...

Detailed explanation of Vue's sync modifier

Table of contents 1. Instructions 2. Modifiers 3....

Details on how to use class styles in Vue

Table of contents 1. Boolean 2. Expression 3. Mul...

Three examples of blur background effects using CSS3

Let’s not start with the introduction and get str...

Detailed tutorial on installing harbor private warehouse using docker compose

Overview What is harbor? The English word means: ...

9 Practical CSS Properties Web Front-end Developers Must Know

1. Rounded Corners Today's web designs are con...

Design Theory: Text Legibility and Readability

<br />Not long ago, due to business needs, I...

Vue2.x - Example of using anti-shake and throttling

Table of contents utils: Use in vue: explain: Ima...

CocosCreator Skeleton Animation Dragon Bones

CocosCreator version 2.3.4 Dragon bone animation ...

Linux ssh server configuration code example

Use the following terminal command to install the...

Nginx uses reverse proxy to implement load balancing process analysis

Introduction Based on docker container and docker...

MySQL intercepts the sql statement of the string function

1. left(name,4) intercepts the 4 characters on th...