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

  1. It does not copy the object’s inherited properties
  2. It does not copy the object’s non-enumerable properties
  3. 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

  1. 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
  2. Copying the Date reference type becomes a string
  3. Unable to copy non-enumerable properties
  4. Unable to copy the object’s prototype chain
  5. Copying the RegExp reference type becomes an empty object
  6. Object containing NaN, Infinity, and -infinity will result in NULL JSON serialization
  7. [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

  1. Non-enumerable attributes and Symbol types cannot be copied
  2. Can only be used for common values do copy a reference type For example, the Date | Function | RegExp…). Don’t can
  3. 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