Object deep copy and shallow copy

JavaScript variables contain two types of values

1. Basic type values: simple data segments stored in the stack.

String, Number, Undefined, Null, Boolean, Symbol, bigIntCopy the code

2. Reference type value: Reference type value is an instance of the reference type. Is an object stored in heap memory.

Reference type is a data structure, the most commonly used are Object,Array,function, in addition to Date,RegExp,Error, etc. ES6 provides a Set,Map2 new data structure.

How does JavaScript copy reference types?

Basic types are assigned differently than reference types.

When a variable copies a reference type value, it copies the value of the variable to the new variable in the same way as a primitive type value, except that the value of the variable is a pointer to an object stored in the heap.

JS specifies that an object in the heap cannot be accessed directly. You must access the address of the object in the heap, and then obtain the value of the object according to the address, so the value of the reference type is accessed by reference.

let obj1 = {a:1};
let obj2 = obj1;
obj2.a = 2;
console.log(obj1); //{a:2}
console.log(obj2); //{a:2}
Copy the code

The value of the variable, the pointer, is stored on the stack, and when obj1 copies the value of the variable to obj2, obj1,obj2 is just a pointer on the stack, pointing to the same object in the heap, so when obj1 is used to manipulate objects in the heap,obj2 also changes.

Shallow copy

Creates a new object that has an exact copy of the property values of the original object. If the property is of a primitive type, the value of the primitive type is copied, and if the property is of a reference type, the memory address is copied, so if one object changes the address, the other object is affected.

JavaScript provides shallow copy methods:

  1. Object.assign()
let target = {};
let source = { a: { b: 2}};Object.assign(target, source);
console.log(target); // { a: { b: 2 } };
Copy the code

Object.assign only creates a new Object in the root property (the first level of the Object), but copies the same memory address if the value of the property is an Object

  1. Properties inherited by objects are not copied

  2. Properties that cannot be enumerated

  3. The data property/accessor property of the

  4. You can copy the Symbol type

  5. Extension operator (…)

let obj = {a:1.b: {c:1}}
letobj2 = {... obj}; obj.a=2;
console.log(obj); //{a:2,b:{c:1}}
console.log(obj2); //{a:1,b:{c:1}}

obj.b.c = 2;
console.log(obj); //{a:2,b:{c:2}}
console.log(obj2); //{a:1,b:{c:2}}

Copy the code

It is not possible to copy a property whose value is an object into two different objects, but it is more convenient to use the extension operator if the property is a value of a primitive type

  1. Array.prototype.slice

The slice() method returns a new array object, leaving the original array unchanged.

This object is a shallow copy of the original array determined by begin and end (not including end).

  1. Array.prototype.concat

The concat method for arrays is also a shallow copy.

Concatenating an array that contains a reference type requires that any changes to the attributes of the elements in the original array are reflected in the concatenated array.

let arr=[{ a:1}, {a:1}, {a:1}] 
let arr2=[{b:1}, {b:1}, {b:1}]
let arr3=arr.concat(arr2)
arr2[0].b=123
console.1og(arr3) //[{"a":1},{"a":1),("a":1},("b":123},("b":1},("b":1}]
Copy the code

Deep copy

A shallow copy simply creates a new object in the heap, copying the value of the basic type, whereas a complex data type, or object, copies the same address.

A deep copy is a complex data type that creates a memory address in the heap to store the copied object and copies the original object over. The two objects are independent of each other, that is, two different addresses.

A complete copy of an object from memory, from the heap memory to open a new area to store the new object, and the new object changes will not affect the original object.

Deep copy method:

  1. Json.stringify (), json.parse () serialize and dissequence

    Json.stringify () is by far the most common deep copy method used in front-end development.

    The idea is to serialize an object into a JSON string, convert the contents of the object into a string and save it on disk, and then deserialize the JSON string into a new object using json.parse ().

let obj1 = {
    a:1.b: [1.2.3]}let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)
console.log(obj2); / / {a: 1, b: [1, 2, 3]}
obj1.a = 2
obj1.b.push(4);
console.log(obj1); / / {2, a: b: [1, 2, 3, 4]}
console.log(obj2); / / {a: 1, b: [1, 2, 3]}

Copy the code

There are a few caveat to implementing deep copy with json.stringify

  1. If there is function, undefined, or symbol in the value of the copied object, passJSON.stringify()serializedJSONThe key-value pair in the string will disappear
  2. Cannot copy non-enumerable properties, cannot copy the prototype chain of an object
  3. Copying the Date reference type becomes a string
  4. copyRegExpThe reference type becomes an empty object
  5. Object containingNaN,Infinityand-Infinity, the serialized result becomesnull
  6. (obj[key] = obj)

Reprint statement:

Author: yeyan1996

Links: juejin. Cn/post / 684490…