Deep and shallow copy of JavaScript is often used in practical applications. Before understanding deep copy and shallow copy, we need to first understand the two data types of JavaScript. The storage mode of JavaScript data type is also the principle of deep copy and shallow copy.

Primitive types and reference types

Values of basic types have a fixed size and space in memory, and values are stored in memory stacks; The size of a reference type value is not fixed, the value is stored in the heap in memory, and properties and methods can be added dynamically.

Value type (base type)

String, Number, Boolean, Null, and Undefined, Symbol.Copy the code

Reference data type

Object, Array, Function.Copy the code

Stack memory and heap memory

Why do base data types stay on the stack and reference data types in the heap? 1. The heap is larger than the stack, and the stack is faster than the stack. 2. The basic data types are relatively stable and occupy relatively small memory; 3. Reference data type size is dynamic, and it is infinite, the size of the reference values will change, not on the stack, otherwise it will reduce the speed of the variable to find, so the value of the variables on the stack space is the address of the object is stored in the heap, address size is fixed, so it is stored in a stack on the variable performance without any negative effects; 4. The heap memory is unordered storage, which can be obtained directly by reference.

Stack memory (stack)

Stack memory is commonly known as scope: global scope (Window) and private scope. 1. Stack Automatically allocates space to the system. The size is fixed and the system automatically releases the space. 2. Provide a top-down execution environment for JavaScript; 3. Because the values of basic data types are relatively simple, they are used to create a place in stack memory directly to store the values; 4. When stack memory is destroyed, the values of the stored basic data types are also destroyed.

Heap memory (heap)

1. Memory allocated dynamically when heap is used. The memory size varies and will not be automatically released. 2. Store values of reference types; 3. If the heap is not occupied by any variables or other objects, the browser will reclaim the heap when it is idle and destroy all unused heap memory.

Stack memory connections

When we need to access a value of a reference type, we first get a pointer to the object from stack memory, and then get the data we need from the heap memory.

    let a = 1;
    let b = 2;
    let c = {obj: 123};
Copy the code

The variable a is stored in the stack memory, and its value is the basic data type (Number), so it is naturally in the stack memory. Since there is no 1 in the stack memory, we take out a block of memory to store 1. This variable A refers to the address of the stack memory with the fast value of 1. If there is an address in the stack memory that holds a 1 during assignment, the address is directly referred to the stack memory. The value of the reference type is stored in the heap memory, which means that the variable is actually a pointer to another location in memory, which is the heap memory.

Shallow copy and deep copy

In plain English, objB copies objA. When an objA is modified, it is a shallow copy if the objB is changed, and a deep copy if the objB is not modified. The difference between shallow copy and deep copy is that shallow copy copies only the first layer properties of an object, while deep copy can recursively copy the properties of an object.

Shallow copy

Creates a new object with an exact copy of the original object property values. If the property is a primitive type, it copies the value of the primitive type, and if the property is a reference type, it copies the memory address, so if one object changes the address, it affects the other object.

    let objA = {a:0.b:1.c:2}, objB = objA;
    console.log(objA, objB);
Copy the code

The printed result is

Then we modify the original object

    objA.a = 3;
    console.log(objA, objB);
Copy the code

The printed result is

Deep copy

To make a complete copy of an object out of memory, a new area of heap memory is created to hold the new object, and modification of the new object does not affect the original object.

JSON.stringify(JSON.parse(object))

Json.stringify (json.parse (object)) is often used for relatively simple deep copies, but this approach has many disadvantages (undefined, symbol, and functions are lost when serialized; New Date() is serialized as a string rather than a time object; Regular and Error objects can only be serialized as empty objects; NaN, Infinity, and -infinity become null when serialized; An enumerable property of an object that can only be serialized; Unable to resolve circular references)

Shallow copy plus recursive implementation (only consider common object and array data types)
function deepClone(obj) {
  let objClone = Array.isArray(obj)? [] : {};if(obj && typeof obj==="object") {
    for(key in obj) {
      if(obj.hasOwnProperty(key)) {
         // Determine whether the oJB child is an object, if so, recursively copy
          if(obj[key]&&typeof obj[key] ==="object") {
              objClone[key] = deepClone(obj[key]);
          }else {
              // If not, simply copyobjClone[key] = obj[key]; }}}}return objClone;
} 
Copy the code