⭐ ⭐ ⭐

Requirements:

  • Supports object, array, date, re copy.
  • Handle primitive types (primitive types return directly; only reference types have the concept of deep copy).
  • Handle Symbol as the key name.
  • Handling functions (functions return directly, there is no point in copying functions, two objects use functions with the same address in memory, there is no problem).
  • Handle DOM elements (DOM elements are returned directly, there is no point copying DOM elements, they all point to the same page).
  • Open up an additional storage space, WeakMap, to solve the problem of cyclic reference recursive stack explosion (introduce another meaning of WeakMap, with garbage collection mechanism, to prevent memory leakage).

A:

function deepClone (target, hash = new WeakMap(a)) { // Create an extra storage space, WeakMap, to store the current object
  if (target === null) return target // If null, no copy operation is performed
  if (target instanceof Date) return new Date(target) // Processing date
  if (target instanceof RegExp) return new RegExp(target) // Process the re
  if (target instanceof HTMLElement) return target // Handle DOM elements

  if (typeoftarget ! = ='object') return target // Handle primitive types and functions without deep copy, return directly

  // Deep copy is required for reference type
  if (hash.get(target)) return hash.get(target) // When you want to copy the current object, first go to the storage space to find, if there is a direct return
  const cloneTarget = new target.constructor() // Create a new clone object or clone array
  hash.set(target, cloneTarget) // If there is no storage space, store it in the hash

  Reflect.ownKeys(target).forEach(key= > { // introduce reflect. ownKeys to handle Symbol as the key name
    cloneTarget[key] = deepClone(target[key], hash) // Copy each layer recursively
  })
  return cloneTarget // Returns the cloned object
}
Copy the code

Test it out:

const obj = {
  a: true.b: 100.c: 'str'.d: undefined.e: null.f: Symbol('f'),
  g: {
    g1: {} // Deep objects
  },
  h: []./ / array
  i: new Date(), // Date
  j: /abc/./ / regular
  k: function () {}, / / function
  l: [document.getElementById('foo')] // Introduce the meaning of WeakMap to handle DOM elements that may be cleared
}

obj.obj = obj // Circular reference

const name = Symbol('name')
obj[name] = 'lin'  // Symbol is the key

const newObj = deepClone(obj)

console.log(newObj)
Copy the code

The process of writing deep copies by hand can be found in this article:

Easy to get JS shallow copy, deep copy

At the end

If my article is helpful to you, your 👍 is my biggest support ^_^

I’m Allyn, export insight technology, goodbye!

The last:

“Front End daily Question (16)” The difference between deep copy and shallow copy?

Next up:

How to convert pseudo-arrays into arrays in JS