Skip to content

Instantly share code, notes, and snippets.

@gangsthub
Last active September 29, 2023 01:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gangsthub/0bce1161cfd2aa91ae7cad9abb42c342 to your computer and use it in GitHub Desktop.
Save gangsthub/0bce1161cfd2aa91ae7cad9abb42c342 to your computer and use it in GitHub Desktop.
DeepClone-js: JS utility with circular replacer

DeepClone-js

Utility to clean up circular references while creating a new reference of an object performing a deep copy (as oposite to a shallow copy). Bear in mind it doesn't work with some data types: Date, Map, RegExp, Set, TypedArray...

📦 Install

npm i -S gist:0bce1161cfd2aa91ae7cad9abb42c342

Usage

import { deepClone } from 'deepclone-js'

const source = {
  b: 1,
}

const original = { ...source }
original.c = original // 👉🏼 Circular reference

const copy = deepClone(original)
// expect(copy).toEqual(source) // -> true
/**
* @param {Object} object
* @returns {Boolean}
*/
const isFalsy /* So, it's not an object */ = object => !object
/**
* Matches object type
* @param {Object} object
* @returns {Boolean}
*/
export const isObjectType = object => !!(typeof object).match(/object/)
/**
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#Examples
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
*/
const getCircularReplacer = () => {
const seen = new WeakSet()
return (_key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return
}
seen.add(value)
}
return value
}
}
/**
* @param {Object} object The object to be cloned
* @returns A copied value representing a new reference and discarding circular references
*/
export const deepClone = object => {
if (isFalsy(object)) return {}
if (!isObjectType(object)) return object
return JSON.parse(JSON.stringify(object, getCircularReplacer()))
}
{
"version": "0.0.3",
"name": "deepclone-js",
"main": "deepClone.js"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment