The so-called clone is the copy, normally speaking, the copy should not affect the original, but the fact is not the case, so there is a deep clone. Directly on the code theory (convenient for everyone to see, so the screenshot of this)
As you can see, shallow clones only clone the first layer. The o objects in cloneObj and obj still point to the same heap memory, so when assigning a new value to cloneobj.o.x, the value of obj.o.x changes.
So if it’s a deep clone and whatever cloneObj changes, it doesn’t affect the value of obj, right
In addition to shallow cloning using extended operators, there are:
Object.assign()
const obj1 = {a: 1, b: 2}
const obj2 = Object.assign({}, obj1)
Copy the code
for… in
let obj1 = { name: "bob", age: 18, sex: "man", o: { x: 1 } } let obj2 = {} for(let key in obj1){ // fon.. In iterates through the methods on the prototype, so prevent iterating through the prototype if(! obj1.hasOwnProperty(key)) break; Obj2 [key] = obj1[key]}Copy the code
Object.keys()
Let obj1 = {name: "Bob ", age: 18, sex: "man", o: {x: 1}} let obj2 = {} // with for... For (let key object.keys (obj1) {obj2[key] = obj1[key]}Copy the code
Implement deep cloning
If the attribute values in the object are not functions, undefined, symbol, etc
Json. stringify and json. parse are generally simple and crude
let obj1 = { name: "bob", age: 18, sex: "man", o: { x: Parse (json.stringify (obj1)) obj2.o.x = 2 console.log(obj1.o.x) // Not affected by obj2, still 1Copy the code
Of course, special processing is required to implement procloning of special values
Recursive methods to achieve deep cloning
Const cloneDeep = (target, hash = new WeakMap()) => {// If (typeof target! = = 'object' | | target = = = null) {return target} / / if it is regular if (target instanceof RegExp) {return new RegExp (target)} / / If (target instanceof Date) {return new Date(target)} if (hash. Has (target)) return if (hash hash.get(target) const cloneTarget = Array.isArray(target) ? [] : {} hash.set(target, CloneTarget) / / processing of Symbol attribute const symKeys = Object. GetOwnPropertySymbols (target) if (symKeys. Length) { If (typeof target[sk] === 'object' && target[sk]! == null) {cloneTarget[sk] = cloneDeep(target[sk])} else {cloneTarget[sk] = target[sk]}} And do not iterate over properties on the prototype (using ES6 methods, not for... in) for (let key of Object.keys(target)) { cloneTarget[key] = typeof target[key] === 'object' && target[key] ! == null ? cloneDeep(target[key], hash) : target[key] } return cloneTarget }Copy the code
Validation:
As can be seen, the clone has been implemented, and the clone object clone change does not affect the original object obj