To understand the difference between deep and shallow copies, it is important to know that the main difference between deep and shallow copies is that they are stored in different memory types. Different storage types lead to different storage areas. When it comes to memory storage area, as computer programmers, we should be very familiar with, memory can be divided into heap and stack, where the stack is automatically allocated memory space by the system, and automatically released by the system; The heap is dynamically allocated memory, size is not fixed, by the programmer to allocate and release themselves.

Then we look at data types, because different data types have different storage space. As we all know, JS has basic data types and reference data types. The basic data types are: undefined, Boolean, NULL, number, string. The basic data types are stored in the stack. The size of the data is determined. Note that values of primitive types are immutable!! Values of basic types are immutable!! Values of basic types are immutable!! . Primitive values of primitive types are fundamentally different from reference types such as objects. Primitive values are immutable. No method can change an original value. Modifying a method in a string does not change the string but returns a new string! Primitive values are immutable, which means that no matter how we “modify” them dynamically, we just think we are changing the original value, but in fact we are not changing the original value, but returning a new primitive value. Strings are easy to understand, but what about numbers and booleans? We can give them assign a new value, at first glance is very confused, but as long as it is good to want to understand the operation of memory, such as we define a variable mynum, make it equal to 22, and then we give it a value of 3 again, finally mynum the value of this variable is changed to 3, but the change is not original values are changed, The original number 22 is still 22. This is because we have allocated a chunk of memory on the stack for the variable mynum, and when we reassign, the binary data in this memory is replaced with three pairs of binary data. Let’s not go too far here, just remember that base values cannot be changed. A comparison of primitive data is a comparison of values, which are considered equal as long as the values are equal.

Reference data is stored in the heap, and as anyone who has learned C++ knows, a reference variable is just a pointer to the address of the reference data, which is stored in the stack, but points to an address in the heap where the actual reference data is stored. Reference types of data can be changed, and the comparison of reference type is the comparison of reference, the comparison of reference refers to the comparison between the reference object pointer, compare two reference type data, is to compare the two that is stored in the stack pointer is pointing to the same objects in the heap, if it returns true, if not, return false.

var a = {name: 'mike'};
var b = {name: 'mike'};
console.log(a === b); // false 
Copy the code

Both objects store the same information, but because they have different addresses in the heap, variable A and variable B are not the same.

Once we understand the difference between primitive and reference types, we should be able to understand the difference between value and address. The basic type of assignment is to create a new region on the stack and store the value in that region.

var a = 1; var b = a; a = a + 1; console.log(a); // 2 console.log(b); / / 1Copy the code

As you can see from the above code, assignment of the basic type is performed on two independent variables. They do not affect each other. Changing the value of one variable does not affect the value of the other variable because they are stored in different positions on the stack. The assignment of a reference class is different, passing the value depends on the address passing, changing the pointer pointing, let’s look at the code.

var a = {};
var b = a;
a.name = 'mike';
console.log(a.name); // "mike"
console.log(b.name); // "mike"
b.age = 23;
console.log(a.age); // 23
console.log(b.age); // 23
console.log(a === b); // true
Copy the code

By setting b equal to a, the variable B or the pointer B also points to the same empty object in the heap that the pointer to A points to, and when you modify that object through any pointer, it works, so that variable A and variable B interact.

OK, with that in mind, let’s start talking about shallow copy and deep copy. For simple assignment operations, it is also important to distinguish data types. If the assignment is to a base value, the new memory space is created, and the operation on the new memory space does not affect the original data. If you assign a value using a reference type, you are actually referring to the same memory region in the heap, modifying the same object, and affecting each other. What about shallow copies? A shallow copy of an object’s primitive type property values resets the memory space and does not affect the original object. However, attribute values of reference type inside the object will not be reopened, thus affecting the original object. What about deep copy? Deep copy goes one step further than shallow copy in that it clears up memory for both the primitive type attributes of the object and its children.