This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

1. Handwritten 62+ method to learn the basic principles of JavaScript

To determine if an object has a cyclic reference indexed to the source code implementations, you can also click on isCyclic to quickly view the 62+ handwritten implementations available so far.

2. Circular references that have to be said

I’m sure you’ve had a similar problem before. Circular references can occur if two objects pass references to each other or if references to attributes of the object themselves.

Circular references were a cause of memory leaks in older browsers, but with improved garbage collection algorithms that now handle circular references well, this is no longer a problem.

This article will take you three minutes to learn along

  1. What situations might cause circular references (important)?
  2. How do I determine if an object has a circular reference (important)?

3. Several cases of circular reference

There are two common cases of circular references: objects refer to each other, and objects’ properties refer to the objects themselves

3.1 Objects Reference Each other

let obj1 = { name: 'Bighead Head 1' }
let obj2 = { name: 'Bighead Head 2' }
// The properties of object 1 refer to object 2
obj1.obj = obj2
// The properties of object 2 refer to object 1
obj2.obj = obj1

Copy the code

3.2 Properties of an object refer to the object itself

1. Reference the outermost object directly

let obj = { name: 'Bighead Head 1' }
// The attributes of the object refer to the object itself
obj.child = obj

Copy the code

2. Reference some attributes of the object


let obj = {
  name: 'Front End Bighead'.child: {}
}

obj.child.obj = obj.child
Copy the code

4. How to determine whether objects have circular references?

Depending on how many times a circular reference can occur, we can try writing the following code

4.1 Source code implementation

const isCyclic = (obj) = > {
  // Use the Set data type to store detected objects
  let stackSet = new Set(a)let detected = false

  const detect = (obj) = > {
    // If it is not an object type, you can skip it
    if (obj && typeofobj ! ='object') {
      return
    }
    // A circular reference exists when the object to be checked already exists in stackSet
    if (stackSet.has(obj)) {
      return detected = true
    }
    // Save the current obj as stackSet
    stackSet.add(obj)

    for (let key in obj) {
      // Check the attributes under obj one by one
      if (obj.hasOwnProperty(key)) {
        detect(obj[key])
      }
    }
    // After horizontal detection is complete, delete the current object to prevent misjudgment
    } let obj4 = {obj1: tempObj, obj2: tempObj} */ let obj4 = {obj1: tempObj, obj2: tempObj
    stackSet.delete(obj)
  }

  detect(obj)

  return detected
}


Copy the code

4.2 Test a handful

// 1. Objects reference each other

let obj1 = { name: 'Bighead Head 1' }
let obj2 = { name: 'Bighead Head 2' }
// The properties of object 1 refer to object 2
obj1.obj = obj2
// The properties of object 2 refer to object 1
obj2.obj = obj1

console.log(isCyclic(obj1)) // true
console.log(isCyclic(obj2)) // true

// 2. The attributes of the object refer to the object itself

let obj = { name: 'Bighead Head 1' }
// The attributes of the object refer to the object itself
obj.child = obj

console.log(isCyclic(obj)) // true

// 3. Attributes of the object refer to some attributes

let obj3 = {
  name: 'Front End Bighead'.child: {}
}

obj3.child.obj = obj3.child

console.log(isCyclic(obj3)) // true

// 4. Object attributes point to the same reference
let tempObj = {
  name: 'Front End Bighead'
}
let obj4 = {
  obj1: tempObj,
  obj2: tempObj
}

console.log(isCyclic(obj4)) // false

// 5. Other data types

console.log(isCyclic(1)) // false
console.log(isCyclic('Front End Bighead')) // false
console.log(isCyclic(false)) // false
console.log(isCyclic(null)) // false
console.log(isCyclic(undefined)) // false
console.log(isCyclic([])) // false
console.log(isCyclic(Symbol('Front End Bighead'))) // false

Copy the code

5. At the end

A very small knowledge point, thank you for reading. Explore some interesting topics further if you are interested:

Such as:

  1. How to inJSON.stringifyTo output objects that have circular references.
  2. JS garbage collection mechanism is how to deal with circular references and so on.