Skip to content

Instantly share code, notes, and snippets.

@JakeChampion
Last active July 15, 2020 11:10
Show Gist options
  • Save JakeChampion/e1c593b67c59d0f75c7ca3c1cb86a21f to your computer and use it in GitHub Desktop.
Save JakeChampion/e1c593b67c59d0f75c7ca3c1cb86a21f to your computer and use it in GitHub Desktop.
Used to find out whether an object contains a circular reference.
/**
* Used to find out whether an object contains a circular reference.
* @param {*} rootObject The object we want to search within for circular references
* @returns {bool} Returns true if a circular reference was found, otherwise returns false
*/
function containsCircularPaths(rootObject) {
// Used to keep track of all the values the rootObject contains
const traversedValues = new WeakSet();
/**
*
* @param {*} currentObj The current object we want to search within for circular references
* @returns {true|undefined} Returns true if a circular reference was found, otherwise returns undefined
*/
function _containsCircularPaths(currentObj) {
// If we already saw this object
// the rootObject contains a circular reference
// and we can stop looking any further
if (traversedValues.has(currentObj)) {
return true;
}
// Only Objects and things which inherit from Objects can contain circular references
// I.E. string/number/boolean/template literals can not contain circular references
if (currentObj instanceof Object) {
traversedValues.add(currentObj);
// Loop through all the values of the current object and
for (const key in currentObj) {
const value = currentObj[key];
// No need to recurse on every value because only things which inherit
// from Objects can contain circular references
if (value instanceof Object) {
if (_containsCircularPaths(value)) {
return true;
}
}
}
}
}
// _containsCircularPaths returns true or undefined.
// By using Boolean we convert the undefined into false.
return Boolean(_containsCircularPaths(rootObject));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment