How to distinguish the deep copy from the shallow copy? In simple terms, suppose B copies A, and when A is modified, see whether B changes. If B also changes, it is A shallow copy, which is short.

1. If it is a basic data type, the name and value are stored in stack memory

var a = 1; b = a; // stack memory creates a new memory space, where b and A are independent b = 2; console.log(a); / / 1Copy the code

Of course, this is not deep copy either, since deep copy itself is only for more complex Object type data.

2. If it is a reference data type, the name is stored in stack memory and the value is stored in heap memory, but the stack memory provides a reference address to the value in heap memory

For example, shallow copy:
! [](//upload-images.jianshu.io/upload_images/15037426-33f5ceb9d7cb0a6e.png? imageMogr2/auto-orient/strip|imageView2/2/w/500/format/webp)

image.png

When b=a is copied, it is actually copying the reference address of A, not the value in the heap.

! [](//upload-images.jianshu.io/upload_images/15037426-7bf9efc3a6e90bea.png? imageMogr2/auto-orient/strip|imageView2/2/w/500/format/webp)

image.png

When a[0]=1, we modify the array, because a and B point to the same address, so naturally B is affected, this is called shallow copy.

! [](//upload-images.jianshu.io/upload_images/15037426-aba3349a798ab52b.png? imageMogr2/auto-orient/strip|imageView2/2/w/500/format/webp)

image.png

Well, what if we created a new memory in the heap for b, just like the basic type, to achieve the effect of deep copy

! [](//upload-images.jianshu.io/upload_images/15037426-3cc2e0e955d177e3.png? imageMogr2/auto-orient/strip|imageView2/2/w/500/format/webp)

image.png

3. The method of shallow copy

(1) For ···in only loop the first layer

Function simpleCopy(obj1) {var obj2 = array.isarray (obj1)? [] : {}; for (let i in obj1) { obj2[i] = obj1[i]; } return obj2; } var obj1 = { a: 1, b: 2, c: { d: 3 } } var obj2 = simpleCopy(obj1); obj2.a = 3; obj2.c.d = 4; alert(obj1.a); // 1 alert(obj2.a); // 3 alert(obj1.c.d); // 4 alert(obj2.c.d); / / 4Copy the code

(2) Object.assign method

var obj = {
    a: 1,
    b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) // 3
Copy the code

(3) Assign directly with =

Let a =,1,2,3,4 [0], b = a; console.log(a===b); a[0]=1; console.log(a,b);Copy the code

! [](//upload-images.jianshu.io/upload_images/15037426-6a06b6f2ee711a5f.png? imageMogr2/auto-orient/strip|imageView2/2/w/248/format/webp)

image.png

4. Methods to implement deep copy

(1) Copy all hierarchy attributes recursively

function deepClone(obj){ let objClone = Array.isArray(obj)? [] : {}; If (obj && typeof obj==="object"){for(key in obj){if(obj. HasOwnProperty (key)){// Determine if ojb child is an object, if so, If (obj[key]&&typeof obj[key] ==="object"){objClone[key] = deepClone(obj[key]); }else{// If not, simply clone objClone[key] = obj[key]; } } } } return objClone; } let a = [1, 2, 3, 4], b = deepClone (a); a[0]=2; console.log(a,b);Copy the code

Results:

! [](//upload-images.jianshu.io/upload_images/15037426-66f503dd14d2bd0f.png? imageMogr2/auto-orient/strip|imageView2/2/w/407/format/webp)

image.png

(2) Deep copy is realized through JSON objects

function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}
Copy the code

Disadvantages: Can’t implement a deep copy of the object method, will be undefined (3) through the jQuery extend method to achieve deep copy

Var array = [1, 2, 3, 4]; var newArray = $.extend(true,[],array); // True indicates the deep copy, false indicates the shallow copyCopy the code

(4) LoDash function library to achieve deep copy

let result = _.cloneDeep(test)
Copy the code

(5) Reflect

Function deepClone(obj) {if (! IsObject (obj)) {throw new Error('obj is not an object! ') } let isArray = Array.isArray(obj) let cloneObj = isArray ? [...obj] : { ... obj } Reflect.ownKeys(cloneObj).forEach(key => { cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }) return cloneObj }Copy the code

(6) Manually implement deep copy

let obj1 = { a: 1, b: 2 } let obj2 = { a: obj1.a, b: obj1.b } obj2.a = 3; alert(obj1.a); // 1 alert(obj2.a); / / 3Copy the code

If the Object value is a primitive type, you can also use object. assign to implement deep copy, but assign it to an empty Object

var obj = { a: 1, b: 2 } var obj1 = Object.assign({}, obj); // obj assigns a null {} obj1.a = 3; The console. The log (obj. A); / / 1Copy the code

! [](//upload-images.jianshu.io/upload_images/15037426-1c7b29547b2a8794.png? imageMogr2/auto-orient/strip|imageView2/2/w/332/format/webp)

image.png

(8) Use slice to realize deep copy of array

Var arr1 = ["1","2","3"]; var arr1 = ["1","2","3"]; var arr2 = arr1.slice(0); arr2[1] = "9"; Console. log(" Array original value: "+ arr1); Console. log(" Array new value: "+ arr2);Copy the code

! [](//upload-images.jianshu.io/upload_images/15037426-a412661f28396034.png? imageMogr2/auto-orient/strip|imageView2/2/w/341/format/webp)

image.png

(9) Use concat to realize the deep copy of the array

Var arr1 = ["1","2","3"]; var arr1 = ["1","2","3"]; var arr2 = arr1.concat(); arr2[1] = "9"; Console. log(" Array original value: "+ arr1); Console. log(" Array new value: "+ arr2); Var arr1 = [{a:1},{b:2},{c:3}]; var arr2 = arr1.concat(); arr2[0].a = "9"; Console. log(" array original value: "+ arr1[0].a); // Original value of array: 9 console.log(" new value of array: "+ arr2[0].a); // Array new value: 9Copy the code

! [](//upload-images.jianshu.io/upload_images/15037426-5f64889271b63ce7.png? imageMogr2/auto-orient/strip|imageView2/2/w/326/format/webp)

Create (oldObj) var newObj = object.create (oldObj)

function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; A = initalObj if(prop === obj) {continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; }Copy the code

(11) Use extended operators to achieve deep copy

// When value is a basic data type, such as String, Number, or Boolean, the extended operator can be used to make a deep copy. // When value is a reference type, such as Object, Array, the extended operator can be used to make a deep copy. Var car = {brand: "BMW", price: "380000", length: "5 "} var car = {brand: "BMW", price: "380000", length: "5 "} var car = {... car, price: "500000" } console.log(car1); // {brand: "BMW", price: "500000", length: "5 m "} console.log(car); / / {brand: "BMW", price: "380000", length: "5 m"}Copy the code

The original link www.jianshu.com/p/1c142ec2c…

What happens when you manipulate a primitive array in a WEBGL JS loop? React ShoudComponentUpdate React ShoudComponentUpdate Stop rendering vue why don’t you use 11 methods for deep copy shallow copy Vue vue $nextTick Deep parsing Deep Revealing Promise microtask registration and execution Process How does the V8 engine execute a section of JS code? Http3.0 2.0 1.0 compare macro tasks and micro tasks in detail