Topic:

Please complete the JavaScript code that requires a deep copy of the object’s parameters and returns the copied new object.

Question difficulty: Medium

Note:

  1. You need to consider functions, re’s, dates, ES6 new objects
  2. Circular references need to be considered

Answer key

C) recursive d) Map

According to the topic request, the realization of deep copy of the object parameters and returns a copy of the new objects, because of the need to consider parameters object and the object of each data item may include the data type of the function, regular, date, ES6 new object and must consider the circular reference, so you need to introduce ES6 new object Map and the judgment of the data types in detail, key steps are:

  1. First check whether the object parameter is “null”, if yes, return “NULL”
  2. Check whether the data type of the object parameter is object. If no, this parameter is returned
  3. If it is a function, a re, a date, or an ES6 new object, then the new instance object generated by the corresponding constructor of the parameter object is returned
  4. Proceed with the following operations if the function still does not end after the above criteria
  5. Retrieves the current parameter object from the Map object. If it can be obtained, it is a circular reference and returns the value of the parameter object in the Map object
  6. If no corresponding value is obtained in the Map object, the parameter object is saved to the Map as a marker
  7. Creates a new object based on whether the parameter’s data type is an array
  8. Iterating over the object arguments, assigning each item to the new object that is returned by the recursive call to the function itself

Refer to the answer

const _completeDeepClone = (target, map = new Map(a)) = > {
    if(target === null) return target
    if(typeoftarget ! = ='object') return target
    const constructor = target.constructor
    if(/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) return new constructor(target)
    if(map.get(target)) return map.get(target)
    map.set(target, true)
    const cloneTarget = Array.isArray(target)? [] : {}for(prop in target) {
        if(target.hasOwnProperty(prop)) {
        	cloneTarget[prop] = _completeDeepClone(target[prop], map)
        }
    }
    return cloneTarget
}
Copy the code

The attached:

Assignment, shallow copy, deep copy difference

And whether the original data points to the same object The first layer of data is the basic data type The raw data contains child objects
The assignment is Change causes the original data to change along with it Change causes the original data to change along with it
Shallow copy no Changes do not change the original data together Change causes the original data to change along with it
Deep copy no Changes do not change the original data together Changes do not change the original data together

Several ways to implement deep copy (two commonly used)

1. JSON conversion

var targetObj = JSON.parse(JSON.stringify(copyObj))
let arr4 = JSON.parse(JSON.stringify(arr))
Copy the code

Disadvantages:

  1. If the object has a function in it, the function cannot be copied;
  2. Unable to copy properties and methods on object prototype chain
  3. Stack overflows occur when the data level is deep.

2. Ordinary recursive functions

function deepCopy( source ) {
if(! isObject(source))return source; // Return if it is not an object
    let target = Array.isArray( source ) ? [] : {} // Array compatibility
    for ( var k in source ) {
    	if (source.hasOwnProperty(k)) {
    		if ( typeof source[ k ] === 'object' ) {
            	target[ k ] = deepCopy( source[ k ] )
        	} else {
            	target[ k ] = source[ k ]
        	}
    	}
    }
    return target
}

function isObject(obj) {
    return typeof obj === 'object'&& obj ! = =null
}
Copy the code

Disadvantages:

  1. Unable to hold a reference;
  2. Stack overflows occur when the data level is deep.

There are other ways to implement deep copy, let me know in the comments section (* ̄)