How to understand shallow copy and deep copy

1, Data type storage There are two data types...
1, Data type storage
2, Shallow copy
3, Deep copy
4, Distinction

1, Data type storage

There are two data types in JavaScript:

  • Basic type

  • reference type

The basic type data is saved in stack memory

Reference type data is stored in heap memory. The variable of reference data type is a reference to the actual object in heap memory and exists in the stack

2, Shallow copy

Shallow copy refers to the creation of new data, which has an accurate copy of the attribute value of the original data

If the attribute is a base type, the value of the base type is copied. If the attribute is a reference type, the memory address is copied

That is, a shallow copy is a copy layer, and a deep reference type is a shared memory address

Here's a simple implementation of a shallow copy

function shallowClone(obj) { const newObj = {}; for(let prop in obj) { if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }

In JavaScript, there are shallow copies:

  • Object.assign

  • Array.prototype.slice(), Array.prototype.concat()

  • Replication using extension operators

Object.assign

var obj = { age: 18, nature: ['smart', 'good'], names: { name1: 'fx', name2: 'xka' }, love: function () { console.log('fx is a great girl') } } var newObj = Object.assign({}, fxObj);

slice()

const fxArr = ["One", "Two", "Three"] const fxArrs = fxArr.slice(0) fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"]

concat()

const fxArr = ["One", "Two", "Three"] const fxArrs = fxArr.concat() fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"]

Extension operator

const fxArr = ["One", "Two", "Three"] const fxArrs = [...fxArr] fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"]

3, Deep copy

Deep copy opens up a new stack. The properties of two objects are the same, but corresponding to two different addresses. Modifying the properties of one object will not change the properties of the other object

Common deep copy methods include:

  • _.cloneDeep()

  • Handwriting loop recursion

JSON.stringify()

const obj2=JSON.parse(JSON.stringify(obj1));

However, there are disadvantages in this method, which ignores undefined, symbol and functions

const obj = { name: 'A', name1: undefined, name3: function() {}, name4: Symbol('A') } const obj2 = JSON.parse(JSON.stringify(obj)); console.log(obj2); //

Circular recursion

function deepClone(obj, hash = new WeakMap()) { if (obj === null) return obj; //  If it is null or undefined, I will not copy if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); //  It could be an object or a normal value    If it's a function, you don't need a deep copy if (typeof obj !== "object") return obj; //  If it is an object, you need to make a deep copy if (hash.get(obj)) return hash.get(obj); let cloneObj = new obj.constructor(); //  The constructor on the prototype of the class is found, and the constructor on the prototype is not found   The constructor points to the current class itself hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { //  Implement a recursive copy cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj; }

4, Distinction

First of all, with the help of two figures, you can see the difference between shallow copy and deep copy more clearly

It is found from the above figure that both shallow copy and deep copy create a new object, but the behavior is different when copying object attributes

Shallow copy only copies the pointer of the attribute to an object, not the object itself. The old and new objects still share the same block of memory. Modifying the object attribute will affect the original object

//  Shallow copy const obj1 = { name : 'init', arr : [1,[2,3],4], }; const obj3=shallowClone(obj1) //  A shallow copy method obj3.name = "update"; obj3.arr[1] = [5,6,7] ; //  Old and new objects still share the same block of memory console.log('obj1',obj1) // obj1 { name: 'init', arr: [ 1, [ 5, 6, 7 ], 4 ] } console.log('obj3',obj3) // obj3 { name: 'update', arr: [ 1, [ 5, 6, 7 ], 4 ] }

But deep copy as like as two peas will create another object that is exactly the same. New objects do not share memory with original objects.

//  Deep copy const obj1 = { name : 'init', arr : [1,[2,3],4], }; const obj4=deepClone(obj1) //  A deep copy method obj4.name = "update"; obj4.arr[1] = [5,6,7] ; //  The new object does not share memory with the original object console.log('obj1',obj1) // obj1 { name: 'init', arr: [ 1, [ 2, 3 ], 4 ] } console.log('obj4',obj4) // obj4 { name: 'update', arr: [ 1, [ 5, 6, 7 ], 4 ] }

Summary

If the copy type is reference type:

  • Shallow copy is a copy layer. When the attribute is an object, shallow copy is a copy, and the two objects point to the same address

  • Deep copy is a recursive deep copy. When the attribute is an object, deep copy is a new stack, and the two objects point to different addresses

7 September 2021, 16:44 | Views: 8454

Add new comment

For adding a comment, please log in
or create account

0 comments