Detailed explanation of JavaScript object deep copy

Detailed explanation of JavaScript object deep copy

In almost all programming languages, objects are stored as references to variables and copied to other variables. The same is true for the JavaScript language. Therefore, the simple assignment operation to copy is just a transfer of the reference address of the object data, and will not make a complete copy of all the properties inside the object. In other words, when one of the objects is modified, the other variable will also change, because they essentially point to the same object reference.

let obj={
    a:1
};
let copyObj=obj;
obj.a=2;
//输出2
console.log(copyObj.a);

This language feature is sometimes beneficial to developers. But sometimes, a specific development scenario requires a "full copy" of the object, that is, the copied object and the pre-copy object are completely independent and do not affect each other. This process is called " deep copy ". Correspondingly, the previous simple assignment copy operation is called " shallow copy ".
Deep copy is a question that many JavaScript interviewers will ask, and it often appears in interview scenarios as a topic of handwritten code. The following article will analyze in detail the implementation of deep copy in JavaScript.

JSON copy

The principle of this deep copy method is to use the JSON.parse and JSON.stringify functions to escape the target object once and regenerate it to achieve copying:

//json拷贝,不能正确复制undefined、NaN、函数等数据类型
function jsonCopy(obj1){
    //{"a":[1,2],"b":{"a":"a","b":{"a":1}},"c":true,"d":null}
    let obj2=JSON.stringify(obj1);
    obj2=JSON.parse(obj2);
    return obj2;
}

let a={
    a:[1,2],
    b:{a:'a',b:{a:1}},
    c:true,
    d:null,
    e:undefined,
    f:function(a){return a+1;},
    g:NaN
};

let g=jsonCopy(a);
console.log(g);

The output of the program is as follows:
insert image description here
For common scenarios, JSON copy is the most concise way to write deep copy. But as you can see from the above example, JSON copy does not resolve the f and g properties of the a object . This shows that JSON replication cannot handle some specific data types, such as undefined, NaN, function and other data types (the specific situation depends on the browser). But it is guaranteed that JSON copy can correctly handle object properties of the following data types: array, plain object, number, string, boolean .

recursive copy

This deep copy method uses a recursive function to loop through each attribute of the target object, reassigns each attribute to a new object, and finally returns the new object:

//深拷贝
function deepCopy(obj1,obj2={}){
    for(let i in obj1){
        if(obj1.hasOwnProperty(i)){
            if(Array.isArray(obj1[i])){
                obj2[i]=[];
                deepCopy(obj1[i],obj2[i]);
            }else if(typeof obj1[i]==="function"){
                obj2[i]=obj1[i];
            }else if(obj1[i] instanceof Object){
                obj2[i]={};
                deepCopy(obj1[i],obj2[i]);
            }else{
                obj2[i]=obj1[i];
            }
        }
    }
    return obj2;
}

let a={
    a:[1,2],
    b:{a:'a',b:{a:1}},
    c:true,
    d:null,
    e:undefined,
    f:function(a){return a+1;},
    g:NaN
};

let f=deepCopy(a);
console.log(f);

The output of the program is as follows: As
insert image description here
can be seen from the output of the program, recursive copying can correctly resolve object attributes of all data types. Although recursive calls will retain a function stack at runtime, resulting in a certain amount of memory and computing performance loss. But under normal circumstances, the target object that the developer needs to copy will not be a very deep object (usually, after the depth reaches about 100 layers, the recursive copy will freeze). So recursive copying is a very good deep copy implementation.
But one thing to note is that if the target object has a property of the Function data type, then the JavaScript language itself does not provide developers with a good way to "completely copy" a function, so the function cannot be copied. Copying of functions is still a pass-by-reference (when a mutable property of one of the functions is modified, the function property of the other object is also modified).

Guess you like

Origin blog.csdn.net/yuhk231/article/details/89020288