Shallow copy
Object.assign(target, source)
let target = {}
let source = {a: {b: 2}}
Object.assign(target, source)
console.log(target)
source.a.b = 10
console.log(source)
console.log(target)
Copy the code
The result is shown below:
Pay attention to the point
- It does not copy the object’s inherited properties
- It does not copy the object’s non-enumerable properties
- Properties of type Symbol can be copied
Example:
let obj1 = {
a: {b: 1}
sym: Symbol(1)}Object.defineProperty(obj1, 'inumberable', {
value: 'Non-enumerable properties'.enumberable: false
})
let obj2 = {}
Object.assign(obj2, obj1)
obj1.a.b = 2
console.log('obj1', obj1)
console.log('obj2', obj2)
Copy the code
The result is shown below:
Extended operator
/* A copy of the object */
let obj1 = {
a:1.b: {c: 1}}letobj2 = {... obj1} obj1.a =2
obj1.b.c = 2
console.log('obj1', obj1)
console.log('obj2', obj2)
/* Copy the array */
let arr = [1.2.3]
let newArr = [...arr] // The same effect as arr.slice()
Copy the code
The result is shown below:
Concat copies arrays
let arr = [1.2.3]
let newArr = arr.concat()
newArr[1] = 1000
console.log(arr)
console.log(newArr)
Copy the code
The result is shown in figure
Slice copy array
let arr = [1.2, { val: 3}]
let newArr = arr.slice()
newArr[2].val = 1000
console.log(arr)
Copy the code
The result is shown below:
Implement shallow copy manually
const shallowCopy = (target) = > {
if (typeof target === 'object'&& target ! = =null) {
const cloneTarget = Array.isArray(target) ? [] : {}for (let prop in target) {
if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = target[prop]
}
}
return cloneTarget
} else {
return target
}
}
Copy the code
Deep copy
JSON.stringify()
let obj1 = {
a: 1.b: [1.2.3]}let obj2 = JSON.parse(JSON.stringify(obj1))
obj1.a = 2
obj1.b.push(4)
console.log('obj1', obj1)
console.log('obj2', obj2)
Copy the code
The result is shown below:
Pay attention to the point
- If the value of the copied object is function, undefined, or symbol, the key/value pair will disappear in the string serialized by json. stringify
- Copying the Date reference type becomes a string
- Unable to copy non-enumerable properties
- Unable to copy the object’s prototype chain
- Copying the RegExp reference type becomes an empty object
- Object containing NaN, Infinity, and -infinity will result in NULL JSON serialization
- [key] = obj[key] = obj[key] = obj
function Obj {
this.func = function () {
alert(1)}this.obj = { a: 1 }
this.arr = [1.2.3]
this.und = undefined
this.reg = / 123 /
this.date = new Date(0)
this.NaN = NaN
this.infinity = Infinity
this.sym = Symbol(1)}let obj1 = new Obj()
Object.defineProperty(obj1, 'inumberable', {
enumerable: false.value: 'inumberable'
}
console.log('obj1', obj1)
let obj2 = JSON.parse(JSON.stringify(obj1))
console.log('obj2', obj2)
Copy the code
The result is shown below:
Simple version (deep copy for handwritten recursion)
function deepClone(obj) {
let cloneObj = {}
for (let key in obj) {
if (typeof obj[key] === 'object') {
cloneObj[key] = deepClone(obj[key])
} else {
cloneObj[key] = obj[key]
}
}
return cloneObj
}
Copy the code
Pay attention to the point
- Non-enumerable attributes and Symbol types cannot be copied
- Can only be used for common values do copy a reference type For example, the Date | Function | RegExp…). Don’t can
- Object properties inside the loop, i.e. circular reference is not resolved
Improved version (deep copy for handwritten recursion)
const isComplexDateType = (obj) = >
(typeof obj === 'object' || typeof obj === function) && (obj! = =null)
const deepClone = function(obj, hash = new WeakMap(a)) {
if (obj.constructor === Date) {
return new Date(obj)
}
if (obj.constructor === RegExp) {
return new RegExp()}if (hash.has(obj)) return hash.get(obj)
let allDesc = Object.getOwnPropertyDescriptors(obj)
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
for (let key of Reflect.ownKeys(obj)) {
cloneObj = (isComplexDateType(obj[key]) && typeofobj[key] ! = ='function')? deepClone(obj[key], hash) : cloneObj[key] }return cloneObj
}
Copy the code