js implements deep copy

type function

First of all, we need to implement a getType function to judge the type of the element and call the Object.prototype.toString method directly.

function getType(obj){
        // tostring will return constructors corresponding to different labels 
       var toString = Object.prototype.toString;
        var map = {
           '[object Boolean]' : 'boolean' , 
           '[object Number]' : ' number' , 
           '[object String]' : 'string' , 
           '[object Function]' : 'function' , 
           '[object Array]' : 'array' , 
           '[object Date]' : 'date' , 
           '[object RegExp]' : 'regExp' , 
           '[object Undefined]': 'undefined',
          '[object Null]'     : 'null', 
          '[object Object]'   : 'object'
      };
      if(obj instanceof Element) {
           return 'element';
      }
      return map[toString.call(obj)];
   }

deep copy (deepClone)

For a reference type, if you assign it directly to another variable, since the two references point to the same address, changing any one of the references will affect the other. Deep copy is used when we want to copy an object and cut off the connection with this object. For an object, since there may be multiple layers of structure, we can use recursion to solve this problem

function deepClone(data){
       var type = getType(data);
       var obj;
       if(type === 'array'){
           obj = [];
       } else if(type === 'object'){
           obj = {};
       } else {
            // no longer have the next level of 
           return data;
       }
       if(type === 'array'){
           for(var i = 0, len = data.length; i < len; i++){
               obj.push(deepClone(data[i]));
           }
       } else if(type === 'object'){
           for(var key in data){
               obj[key] = deepClone(data[key]);
           }
       }
       return obj;
   }

For the function type, here is a direct assignment or a shared memory value. This is because the function is more to complete some functions, has an input value and a return value, and for the upper-level business, it is more to complete the business function, and there is no need to really deep copy the function.

breadth-first traversal

The above is to use recursion for deep copying, obviously we can use the breadth-first traversal of the tree to achieve

// For the convenience of reading, only the object is deeply copied here. For the judgment of the array, refer to the above example 
   function deepClone(data){
        var obj = {};
        var originQueue = [data];
        var copyQueue = [obj];
        // The following two A queue is used to store the objects visited during the copy process, in order to avoid the problem of object rings (a property value of the object is the object itself) 
       var visitQueue = [];
        var copyVisitQueue = [];
        while (originQueue.length > 0 ){
            var _data = originQueue.shift();
            var _obj = copyQueue.shift();
           visitQueue.push(_data);
           copyVisitQueue.push (_obj);
           for(var key in _data){
               var _value = _data[key]
               if(typeof _value !== 'object'){
                   _obj[key] = _value;
               } else {
                    // Use indexOf to find out whether there are the same objects in the array (the difficulty of implementing indexOf is object comparison) 
                   var index = visitQueue.indexOf(_value);
                    if (index >= 0 ){
                        // A loop occurs No need to take out the traversal 
                       _obj[key] = copyVisitQueue[index];
                   } else {
                       originQueue.push(_value);
                       _obj[key] = {};
                       copyQueue.push(_obj[key]);
                   }
               }
           }
       }
       return obj;
   }

JSON

There is another solution for deep copy objects. When the object does not contain functions, use JSON parsing and reverse parsing to get a deep copy object.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325301608&siteId=291194637