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:
- You need to consider functions, re’s, dates, ES6 new objects
- 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:
- First check whether the object parameter is “null”, if yes, return “NULL”
- Check whether the data type of the object parameter is object. If no, this parameter is returned
- 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
- Proceed with the following operations if the function still does not end after the above criteria
- 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
- If no corresponding value is obtained in the Map object, the parameter object is saved to the Map as a marker
- Creates a new object based on whether the parameter’s data type is an array
- 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:
- If the object has a function in it, the function cannot be copied;
- Unable to copy properties and methods on object prototype chain
- 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:
- Unable to hold a reference;
- Stack overflows occur when the data level is deep.
There are other ways to implement deep copy, let me know in the comments section (* ̄)