Detecting and fixing circular references in JavaScript

后端 未结 15 859
庸人自扰
庸人自扰 2020-11-28 23:29

Given I have a circular reference in a large JavaScript object

And I try JSON.stringify(problematicObject)

And the browser throws

15条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-29 00:00

    Here is a Node ES6 version mixed from the answers from @Aaron V and @user4976005, it fixes the problem with the call to hasOwnProperty:

    const isCyclic = (obj => {
      const keys = []
      const stack = []
      const stackSet = new Set()
      let detected = false
    
      const detect = ((object, key) => {
        if (!(object instanceof Object))
          return
    
        if (stackSet.has(object)) { // it's cyclic! Print the object and its locations.
          const oldindex = stack.indexOf(object)
          const l1 = `${keys.join('.')}.${key}`
          const l2 = keys.slice(0, oldindex + 1).join('.')
          console.log(`CIRCULAR: ${l1} = ${l2} = ${object}`)
          console.log(object)
          detected = true
          return
        }
    
        keys.push(key)
        stack.push(object)
        stackSet.add(object)
        Object.keys(object).forEach(k => { // dive on the object's children
          if (k && Object.prototype.hasOwnProperty.call(object, k))
            detect(object[k], k)
        })
    
        keys.pop()
        stack.pop()
        stackSet.delete(object)
      })
    
      detect(obj, 'obj')
      return detected
    })
    

提交回复
热议问题