Detecting and fixing circular references in JavaScript

后端 未结 15 868
庸人自扰
庸人自扰 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-28 23:59

    I just made this. It may be dirty, but works anyway... :P

    function dump(orig){
      var inspectedObjects = [];
      console.log('== DUMP ==');
      (function _dump(o,t){
        console.log(t+' Type '+(typeof o));
        for(var i in o){
          if(o[i] === orig){
            console.log(t+' '+i+': [recursive]'); 
            continue;
          }
          var ind = 1+inspectedObjects.indexOf(o[i]);
          if(ind>0) console.log(t+' '+i+':  [already inspected ('+ind+')]');
          else{
            console.log(t+' '+i+': ('+inspectedObjects.push(o[i])+')');
            _dump(o[i],t+'>>');
          }
        }
      }(orig,'>'));
    }
    

    Then

    var a = [1,2,3], b = [a,4,5,6], c = {'x':a,'y':b};
    a.push(c); dump(c);
    

    Says

    == DUMP ==
    > Type object
    > x: (1)
    >>> Type object
    >>> 0: (2)
    >>>>> Type number
    >>> 1: (3)
    >>>>> Type number
    >>> 2: (4)
    >>>>> Type number
    >>> 3: [recursive]
    > y: (5)
    >>> Type object
    >>> 0:  [already inspected (1)]
    >>> 1: (6)
    >>>>> Type number
    >>> 2: (7)
    >>>>> Type number
    >>> 3: (8)
    >>>>> Type number
    

    This tells that c.x[3] is equal to c, and c.x = c.y[0].

    Or, a little edit to this function can tell you what you need...

    function findRecursive(orig){
      var inspectedObjects = [];
      (function _find(o,s){
        for(var i in o){
          if(o[i] === orig){
            console.log('Found: obj.'+s.join('.')+'.'+i); 
            return;
          }
          if(inspectedObjects.indexOf(o[i])>=0) continue;
          else{
            inspectedObjects.push(o[i]);
            s.push(i); _find(o[i],s); s.pop(i);
          }
        }
      }(orig,[]));
    }
    

提交回复
热议问题