Advanced front end Foundation: deep and shallow copy

Deep copy and shallow copy

Copy of basic type

Let's start with a very classic piece of code

var a = 1;
var b = a;
a = 200;
console.log(a);      //200
console.log(b);      //1

We should know the basic type "pass by value" and the reference type "pass by reference". As the basic type, the value is stored in the stack memory, which can be used directly. What is the assignment? Then it will always be what it is and will not be affected by the change of the transfer element. So it is not difficult to understand the reason for the value obtained by the above code.

Copy of reference type

In short, the reference type is to generate a heap memory saved by a pointer. When assigning a reference type, what we write is in the stack memory, that is to say, what we get is actually a pointer (we will not directly get the contents in the stack memory). This pointer is code that points to this reference type in stack memory.

The shallow copy takes effect for the value of the basic type in the object, but it will fail if there is a reference type in the reference type.
The so-called deep and shallow copies are relative to typeof = = = 'object', and arrays are saved with heap correspondence.
Shallow copy: copies the storage address of the object, but points to the same (only solves the first layer, and objects in the object are not applicable)
Deep copy: a complete copy of an individual

  • Shallow copy method: (direct =, Object.assign Most are shallow copies)

=

 let arr1 = [1,3,5];
 let arr2 = arr1;
 arr1[0] = 10;
 console.log(arr2) // [10,3,5]
var obj1 = {
       name: 'Zhang San'
}

var obj2 = obj1;
obj2.name = 'Li Si';

console.log(obj1.name); // 'Lee four'

Object.assign

var obj1 = {
       name: 'Zhang San'
}

var obj2 = Object.assign({}, obj1);
obj2.name = 'Li Si';
console.log(obj1.name);  // 'Zhang three'

So far, the shallow copy is successful, but there are compatibility problems, such as the low-end Android, which need to be noted. But careful friends will definitely do another test, as follows:

var obj1 = {
       name: 'Zhang San',
       friends: {
          name: 'Liu Bei',
          age: 33
      }
}

var obj2 = Object.assign({}, obj1);
obj2.name = 'Li Si';
obj2.friends.name = 'Guan Yu';
console.log(obj1.name);  // 'Zhang three'
console.log(obj1.friends.name);  // 'Guan Yu'

Yes, at this stage, we fail. When objects are nested in objects, Object.assign() can only copy one layer. How to solve this problem? In fact, we need to use the method of deep copy:

var obj1 = {
       name: 'Zhang San',
       friends: {
          name: 'Liu Bei',
          age: 33
      }
}

var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = 'Li Si';
obj2.friends.name = 'Guan Yu';
console.log(obj1.name);  // 'Zhang three'
console.log(obj1.friends.name);  // 'Liu Bei'
  • Deep copy method:
    Json.parse(Json.stringify())
var obj1 = {
       name: 'Zhang San',
       friends: {
          name: 'Liu Bei',
          age: 33
      }
}

var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = 'Li Si';
obj2.friends.name = 'Guan Yu';
console.log(obj1.name);  // 'Zhang three'
console.log(obj1.friends.name);  // 'Liu Bei'

$.extend
... operator

 let arr = [1,3,5];
 let arr1 = [...arr];

Returns the new array methods slice(), contat(), map()

  let arr1 = [2,5,7];
  let arr2 = arr1.slice(0);
  let arr3 = arr1.contat();
  let arr4 = arr1.map(x => x);
  arr2[0] = 4;
 arr1[0] = 99;
console.log(arr1,arr2) // [99,5,7]  [4,5,7] 

The method of copy for in even prototype chain

 let arr = [1,3,5];
 let arr2 = [] ;
 for(var key in arr) {
  arr2[key] = arr[key]
}

Encapsulation method

   /**
     * Judge object type
     * @param {Object} object
     * @return {String} object type
     */
    getType(object) {
        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 (object instanceof Element) {
            return 'element';
        }
        return map[toString.call(object)];
    },
       /**
     * Deep copy of objects
     * @param data Metadata to be copied
     * @return {any} Return new data after copying
     */
    deepClone(data) {
        const type = this.getType(data);
        let obj;

        if (type === 'array') {
            obj = [];
        } else if (type === 'object') {
            obj = {};
        } else {
            //No more next level
            return data;
        }
        if (type === 'array') {
            for (let i = 0, len = data.length; i < len; i++) {
                obj.push(this.deepClone(data[i]));
            }
        } else if (type === 'object') {
            for (let key in data) {
                obj[key] = this.deepClone(data[key]);
            }
        }

        const constructor = data.constructor;
        if (constructor) {
            return Object.assign(new constructor(), obj);
        }
        return obj;
    },
Published 24 original articles, won praise and 10000 visitors+
Private letter follow

Tags: JSON Android

Posted on Wed, 15 Jan 2020 08:00:08 -0500 by stephfox