Fully understand shallow copy and deep copy in JS

Keywords: JSON Attribute

1. Brief introduction of shallow copy and deep copy

Shallow copy: although two objects have the same properties after being copied, they all point to the same memory space

let a = {x: 123}
let b = a
b.x = 234
console.log(b)   // {x: 234}
console.log(a)   // {x: 234}

. operation will cause reference and change of variables at the same address

Deep copy: two objects have no relationship (pointing to different memory space) except for copying the same attributes.

2. Implementation of deep copy

(1) . object deep copy

a. Normal object (single level attribute)

Method 1: ES5 for loop assignment

let souceObj = {x: 1, y: 2}

function clone(souceObj, targetObj = {}) {
    for (const key in souceObj) {
        targetObj[key] = souceObj[key]
    }

    return targetObj
}

let targetObj = clone(souceObj)
targetObj.x = 10
console.log(souceObj)   //{ x: 1, y: 2 }
console.log(targetObj)  //{ x: 10, y: 2 }

Method 2: JSON parse stringify

let souceObj = {x: 1, y: 2}
let targetObj = JSON.parse(JSON.stringify(souceObj))
targetObj.x = 10
console.log(souceObj)   //{ x: 1, y: 2 }
console.log(targetObj)  //{ x: 10, y: 2 }

Method 3: ES6 operator

let souceObj = {x: 1, y: 2}
let targetObj = {...souceObj}
targetObj.x = 10
console.log(souceObj)   //{ x: 1, y: 2 }
console.log(targetObj)  //{ x: 10, y: 2 }

Method 4: ES6 Object.assign()

let souceObj = {x: 1, y: 2}
let targetObj = Object.assign({}, souceObj)
targetObj.x = 10
console.log(souceObj)   //{ x: 1, y: 2 }
console.log(targetObj)  //{ x: 10, y: 2 }

b. Nested objects (multiple attributes: attributes are also objects)

function deepCopy(source, target = {}) {
    let key;
    for (key in source) {
	    // I don't copy the properties above
        if (source.hasOwnProperty(key)) {      
			// If this item is of type object, call deepCopy recursively
            if (typeof(source[key]) === "object") {                                          
                target[key] = Array.isArray(source[key]) ? [] : {};
                deepCopy(source[key], target[key]);
            } else {      
				// If it is not an object type, assign a copy directly
                target[key] = source[key];
            }
        }
    }
    return target;
}

(2) . array deep copy

Method 1: slice method of array

let souceArr = ['one', 'two', 'three']
let targetArr = souceArr.slice(0)
targetArr[1] = 'new two'
console.log(souceArr)   //[ 'one', 'two', 'three' ]
console.log(targetArr)  //[ 'one', 'new two', 'three' ]

Method 2: concat method of array

let souceArr = ['one', 'two', 'three']
let targetArr = souceArr.concat()
targetArr[1] = 'new two'
console.log(souceArr)   //[ 'one', 'two', 'three' ]
console.log(targetArr)  //[ 'one', 'new two', 'three' ]

Deep copy of object array:

Let soucearr = [{'name':'weighting '}, {' name ':'boy'}]; / / original array

[].concat(JSON.parse(JSON.stringify(souceArr)))

Method 3: ES6 operator

let souceArr = ['one', 'two', 'three']
let targetArr = [...souceArr]
targetArr[1] = 'new two'
console.log(souceArr)   //[ 'one', 'two', 'three' ]
console.log(targetArr)  //[ 'one', 'new two', 'three' ]

Method 4: basic method loop traversal

No more code here

Posted by dtyson2000 on Sat, 04 Jan 2020 05:08:10 -0800