js handwritten deep copy

JS handwritten deep copy

Deep copy: Suppose I have an object A, I assign it to B, no matter how I change B, A will not change, that is, deep copy

Shallow copy: Suppose I have a nested object A, I assign it to B, change the nested object in B, A will change accordingly, and change the attribute A of the first layer without changing it, that is shallow copy.

There are many sayings on the Internet that the slice and concat methods of arrays can be used for arrays, or objects can be deep copied by using Object.assign() and ES6 extension operator (…). Objects are useful, but multi-layer nesting does not work. What is multi-layer nesting? There are two layers below. The obj object attribute name is also an object, and it can be nested infinitely. The above method is applicable to the following multi-layer nesting is useless.

var obj = { age: 13, name: { addr: 'sky' } }




The following two methods implement deep copy, regardless of whether you are a layer or multi-layer object.

The first one: brain damage method
function deepClone(obj) {
    
    
    if(typeof obj != 'object') return obj;
    return JSON.parse(JSON.stringify(obj))
}

// 测试
var obj = {
    
    
    name: 123
}
var obj1 = obj;
obj1.name = 345;
console.log(obj.name); // 345 这里看到 我们把obj赋值给obj1 然后修改obj1的name值,obj的name值同样发生了改变
var obj2 = deepClone(obj);
obj2.name = 678
console.log(obj.name); //345 把obj赋值给obj2 然后修改obj2的name值 obj的值不发生改变

The above brain damage method is simple and crude, but there is a flaw:

function deepClone(obj) {
    
    
        if (typeof obj != 'object') return obj;
        return JSON.parse(JSON.stringify(obj))
    }
    // 测试
    var obj = {
    
    
        name: 123
    }
    obj.test = obj
    var obj1 = obj;
    var obj2 = deepClone(obj);

If there is a reference to itself, obj has an attribute named test, and its value is obj itself. At this time, an error is reported. The error is as follows, indicating that the premise of using JSON.parse(JSON.stringify(obj)) is that the object cannot has a reference to itself
insert image description here

The second method: recursive method
function deepClone(obj) {
    
    
    if (typeof obj != 'object') return obj;
    var temp = Array.isArray(obj) ? [] : {
    
    };
    for (let key in obj) {
    
    
        if (obj.hasOwnProperty(key)) {
    
    
            if (obj[key] && typeof obj[key] == 'object') {
    
     // 如果obj[key]还是对象则执行递归
                temp[key] = deepClone(obj[key]); // 递归
            } else {
    
    
                temp[key] = obj[key];
            }
        }
    }
    return temp;
}

var obj = {
    
    
    age: 13,
    name: {
    
    
        addr: '天边'
    }
}

var obj2 = deepClone(obj);
obj2.age = 14
obj2.name.addr = '地心'
console.log(obj.age); //13
console.log(obj.name.addr); //天边

Guess you like

Origin blog.csdn.net/yuanqi3131/article/details/121892177