当前位置:网站首页>Deep copy

Deep copy

2020-11-08 19:00:00 Happy Lu

One 、 We need to review the knowledge

Basic types ( Value type ) And reference types

( Basic types ) Value type :Number,Boolean,String,undefined,null

Reference type :object,Arrary

Two 、 The difference between base type and reference type replication

Value type : Copy operations on value types , It's just a copy of the value , Copying and being copied will point to The two are different The data of .

Reference type : The reference type copies the address . So it turns out that , Copying and being copied will eventually point to The same data .

Example :

//  Basic types 

var a = 1;

var b = a;

a = 2;

console.log(a, b); // 2, 1 ,a b Point to different data 
//  The reference type points to the same data 

var a = {c: 1};

var b = a;

a.c = 2;

console.log(a.c, b.c); // 2, 2  Is full of 2,a b Point to the same data 

3、 ... and 、 The difference between deep copy and shallow copy

Shallow copy : Copy only one layer .
Deep copy : Unlimited copy .

Four 、 Four examples of deep copy

Method 1 :
function clone(source){
   if (!isObject(source)) return source;// Parameter verification is better 
     var target={};
     for(var i in source){
         if(source.hasOwnProperty(source){
              if(typeof source[i] === 'object'){ // Object.prototype.toString.call(source[i] === '[Object Object]'
                  target[i] = clone(source[i])
              }else{
                  target[i] = source[i];
              }
         }
     return target;
}
function isObject(obj){
   return Object.prototype.toString.call(obj === '[Object Object]'
}
Method 2 :
function cloneJSON (source){
 return JSON.parse(JSON.stringfy(source));
}

Method 3 :

function cloneLoop(x) {
    const root = {};
    //  Stack 
    const loopList = [
        {
            parent: root,
            key: undefined,
            data: x,
        }
    ];
    while(loopList.length) {
        //  Depth first 
        const node = loopList.pop();
        const parent = node.parent;
        const key = node.key;
        const data = node.data;
        //  Initialize assignment target ,key by undefined Copy to the parent element , Otherwise copy to the child element 
        let res = parent;
        if (typeof key !== 'undefined') {
            res = parent[key] = {};
        }

        for(let k in data) {
            if (data.hasOwnProperty(k)) {
                if (typeof data[k] === 'object') {
                    //  Next cycle 
                    loopList.push({
                        parent: res,
                        key: k,
                        data: data[k],
                    });
                } else {
                    res[k] = data[k];
                }
            }
        }
    }

    return root;
}
Method four :
//  Keep quoting 
function cloneForce(x) {
    // =============
    const uniqueList = []; //  To heavy 
    // =============
    let root = {}
    //  Circular array 
    const loopList = [
        {
            parent: root,
            key: undefined,
            data: x,
        }
    ];
    while(loopList.length) {
        //  Depth first 
        const node = loopList.pop();
        const parent = node.parent;
        const key = node.key;
        const data = node.data;

        //  Initialize assignment target ,key by undefined Copy to the parent element , Otherwise copy to the child element 
        let res = parent;
        if (typeof key !== 'undefined') {
            res = parent[key] = {};
        }
        
        // =============
        //  Data already exists 
        let uniqueData = find(uniqueList, data);
        if (uniqueData) {
            parent[key] = uniqueData.target;
            break; //  Break this cycle 
        }

        //  The data doesn't exist 
        //  Save source data , The corresponding reference in the copy data 
        uniqueList.push({
            source: data,
            target: res,
        });
        // =============
    
        for(let k in data) {
            if (data.hasOwnProperty(k)) {
                if (typeof data[k] === 'object') {
                    //  Next cycle 
                    loopList.push({
                        parent: res,
                        key: k,
                        data: data[k],
                    });
                } else {
                    res[k] = data[k];
                }
            }
        }
    }

    return root;
}

function find(arr, item) {
    for(let i = 0; i < arr.length; i++) {
        if (arr[i].source === item) {
            return arr[i];
        }
    }

    return null;
}

Quote article :https://segmentfault.com/a/11...

版权声明
本文为[Happy Lu]所创,转载请带上原文链接,感谢