In the process of front-end development, we often encounter the problems of shallow copy and deep copy,
The following is a brief description of the concept, difference and implementation method of shallow copy and deep copy.
concept
Shallow copy:
Shallow copy means that a new object accurately copies the attribute value of the original object. If it is a basic data type, it is the value of the basic data type. If it is a reference data type, it is the memory address. If the reference memory address of one object changes, the other object will also change.
Deep copy:
Compared with shallow copy, if the attribute value is a reference type, it creates a new reference type and copies the corresponding value to it. Therefore, the object obtains a new reference type instead of an original reference type. Deep copy can be implemented with two functions of JSON for some objects. However, because the object format of JSON is more strict than that of js, the conversion will fail if a function or Symbol type value appears in the attribute value.
difference
When the object type is copied, the shallow copy only copies the first layer attributes of the object, and the deep copy can recursively copy the attributes of the object.
Implementation method
Implementation method of shallow copy:
1,Object.assign()
Object.assign() is the copy method of the object in ES6. The first parameter accepted is the target object, and the other parameters are the source object. Usage: object Assign (target, source_1, ···), which can realize shallow copy and deep copy of one-dimensional object.
This method should pay attention to:
- If the target object and the source object have properties with the same name, or multiple source objects have properties with the same name, the subsequent properties will overwrite the previous properties.
- If the function has only one parameter, when the parameter is an object, the object is returned directly; When the parameter is not an object, it will be converted to an object and then returned.
- Because null and undefined cannot be converted into objects, the first parameter cannot be null or undefined, and an error will be reported.
let target = {a: 1}; let object2 = {b: 2}; let object3 = {c: 3}; Object.assign(target,object2,object3); console.log(target); // {a: 1, b: 2, c: 3}
2. Extension operator
Using the extension operator, you can copy attributes when constructing literal objects. Syntax: let cloneObj = {... obj}.
let obj1 = {a:1,b:{c:1}} let obj2 = {...obj1}; obj1.a = 2; console.log(obj1); //{a:2,b:{c:1}} console.log(obj2); //{a:1,b:{c:1}} obj1.b.c = 2; console.log(obj1); //{a:2,b:{c:2}} console.log(obj2); //{a:1,b:{c:2}}
3. Array method to realize shallow copy of array
(1)Array.prototype.slice
slice() method is a method of JavaScript array. This method can return the selected element from the existing array: Usage: array Slice (start, end), which does not change the original array.
This method has two parameters, both of which are optional. If both parameters are not written, a shallow copy of an array can be realized.
let arr = [1,2,3,4]; console.log(arr.slice()); // [1,2,3,4] console.log(arr.slice() === arr); //false
(2)Array.prototype.concat
The concat() method is used to combine two or more arrays. This method does not change the existing array, but returns a new array. This method has two parameters, both of which are optional. If both parameters are not written, a shallow copy of an array can be realized.
let arr = [1,2,3,4]; console.log(arr.concat()); // [1,2,3,4] console.log(arr.concat() === arr); //false
Implementation method of deep copy:
1,JSON.stringify()
JSON.parse(JSON.stringify(obj)) is one of the commonly used deep copy methods. Its principle is to use JSON Stringify serializes js objects (JSON strings), and then uses JSON Parse to deserialize (restore) js objects.
This method can simply and rudely implement deep copy, but there are still problems. If there are functions, undefined and symbol in the copied object, when JSON is used After stringify () is processed, it will disappear.
let obj1 = { a: 0,b: {c: 0}}; let obj2 = JSON.parse(JSON.stringify(obj1)); obj1.a = 1; obj1.b.c = 1; console.log(obj1); // {a: 1, b: {c: 1}} console.log(obj2); // {a: 0, b: {c: 0}}
2. Function library lodash cloneDeep method
The library also provides cloneDeep is used for Deep Copy
var _ = require('lodash'); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; var obj2 = _.cloneDeep(obj1); console.log(obj1.b.f === obj2.b.f);// false
3. Handwritten implementation of deep copy function
// Implementation of deep copy function deepCopy(target, map = new WeakMap()) { let result = null if(Array.isArray(target)){ result = [] }else{ result = {} } //Handling circular dependencies if(map.get(target)){ return map.get(target) }else{ map.set(target.result) } for (let i in target) { if (target.hasOwnProperty(i)) { if(typeof target[i] === 'object'){ result[i] = deepClone(target[i], map) }else{ result[i] = target[i] } } } return result }