Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.
Shallow copy
Creates a new object to accept the object value to be copied or referenced again. If the object property is a primitive data type, the value of the primitive type is copied to the new object. But if the property is a reference data type, the copy is an address in memory, and if one object changes the address in memory, the other object will be affected.
Object.assign
The object.assign () method is used to assign the values of all enumerable properties from one or more source objects to target objects. It will return the target object.
Object.assign(target, ... sources)
const target = { a: 1.b: 2 }
const source = { b: 4.c: 5 }
const returnedTarget = Object.assign(target, source)
console.log(target) // Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget) // Object { a: 1, b: 4, c: 5 }
Copy the code
Note the following when using object. assign:
- It does not copy the object’s inherited properties;
- It does not copy the object’s non-enumerable properties;
- You can copy
Symbol
Type property.
Object.assign
Iterate over the properties of the original object, assigning them to the corresponding properties of the target object by copying
Extended operator
You can use the extension operator to make a shallow copy while constructing an object.
let cloneObj = { ... obj };
/* A copy of the object */
let obj = {a:1.b: {c:1}}
letobj2 = {... obj} obj.a =2
console.log(obj) //{a:2,b:{c:1}}
console.log(obj2) //{a:1,b:{c:1}}
obj.b.c = 2
console.log(obj) //{a:2,b:{c:2}}
console.log(obj2) //{a:1,b:{c:2}}
/* Copy the array */
let arr = [1.2.3]
let newArr = [...arr] / / newArr [1, 2, 3]
Copy the code
Concat copies arrays
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
let arr = [1.2.3]
let newArr = arr.concat()
newArr[1] = 100
console.log(arr) // [1, 2, 3]
console.log(newArr) // [1, 100, 3]
Copy the code
Slice copy array
arr.slice([begin[, end]])
let arr = [1.2, {val: 4}]
let newArr = arr.slice()
newArr[2].val = 1000
console.log(arr) // [ 1, 2, { val: 1000 } ]
Copy the code
Deep copy
A shallow copy simply creates a new object and copies the values of the original object’s primitive type, while a reference data type copies only one layer of properties. Deep copy is different. For complex reference data types, a full memory address is created in the heap and the original object is copied over. The two objects are independent and unaffected.
A complete copy of an object from memory to the target object, and a new space in the heap memory to store the new object, and the modification of the new object does not change the original object, the two achieve true separation.
JSON.stringify()
Json.stringify () serializes an object into a JSON string, converts the contents of the object into a string, and finally generates a new object from the JSON string using json.parse ().
let obj1 = { a:1.b: [1.2.3]}let str = JSON.stringify(obj1)
let obj2 = JSON.parse(str)
console.log(obj2) / / {a: 1, b: [1, 2, 3]}
obj1.a = 2
obj1.b.push(4)
console.log(obj1) / / {2, a: b: [1, 2, 3, 4]}
console.log(obj2) / / {a: 1, b: [1, 2, 3]}
Copy the code
Using json.stringify () requires caution
- If the value of the copied object has a function,
undefined
,symbol
These types, afterJSON.stringify
The key/value pair disappears in the serialized string; - copy
Date
The reference type becomes a string; - Unable to copy non-enumerable properties;
- Unable to copy object’s prototype chain
- copy
RegExp
Reference types become empty objects; - Object containing
NaN
,Infinity
As well as-Infinity
.JSON
The result of serialization will becomenull
; - Looping applications that cannot copy objects, i.e. objects are looped (obj[key] = obj).
The recursive implementation
// Check whether the type is complex
const isComplexDataType = obj= > (typeof obj === 'object' || typeof obj === 'function') && (obj ! = =null)
const deepClone = function (obj, hash = new WeakMap(a)) {
// The date object returns a new date object
if (obj.constructor === Date)
return new Date(obj)
The regular object returns a new regular object directly
if (obj.constructor === RegExp)
return new RegExp(obj)
// If the loop is referenced, use weakMap
if (hash.has(obj)) return hash.get(obj)
/ / the use of Object getOwnPropertyDescriptors method can obtain all attributes of the Object, and the corresponding characteristics
let allDesc = Object.getOwnPropertyDescriptors(obj)
// Walks through the properties of all keys of the passed argument
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
// Inherit the prototype chain
hash.set(obj, cloneObj)
for (let key of Reflect.ownKeys(obj)) {
cloneObj[key] = (isComplexDataType(obj[key]) && typeofobj[key] ! = ='function')? deepClone(obj[key], hash) : obj[key] }return cloneObj
}
// Here is the validation code
let obj = {
num: 0.str: ' '.boolean: true.unf: undefined.nul: null.obj: { name: 'I am an object'.id: 1 },
arr: [0.1.2].func: function () { console.log(I'm a function.)},date: new Date(0),
reg: new RegExp('/ I'm a regular /ig'),Symbol('1')]: 1,}Object.defineProperty(obj, 'innumerable', {
enumerable: false.value: 'Non-enumerable properties'
})
obj = Object.create(obj, Object.getOwnPropertyDescriptors(obj))
obj.loop = obj // Set loop to a property referenced in a loop
let cloneObj = deepClone(obj)
cloneObj.arr.push(4)
console.log('obj', obj)
console.log('cloneObj', cloneObj)
Copy the code
One last word
If this article is helpful to you, or inspired, help pay attention to it, your support is the biggest motivation I insist on writing, thank you for your support.