Обработка циклических ссылок при рекурсивном переборе вложенных объектов на JavaScript

Обработка циклических ссылок при рекурсивном переборе вложенных объектов на JavaScript

JavaScript

var fractal = {
    a1: {
        b1: {
            c: 1
        },
        b2: {
            c: 222
        },
        b3: {
            c: {
                d: 33,
                e: 2.5,
                f: {
                    g: 9999,
                    h: {
                        i: {
                            j: 1001,
                            k: 'строка',
                            l: [1,2,3],
                            m: function() {}
                        }
                    }
                }
            }
        }
    }
}

fractal.a1.b2.m = fractal.a1.b2;

getFiniteValue(fractal);

function getFiniteValue(obj) {
	var handledFlag = 'temp__isAlreadyHandled__';

	getProp(obj);
    	
    function getProp(o, stack) {
		var propertyPath;
        
		for(var prop in o) {
            if(typeof(o[prop]) === 'object') {
                if(!o[prop][handledFlag]) {
                    Object.defineProperty(o[prop],handledFlag, {
					    value: true,
					    writable:false,
						configurable: true
			        });

					if(!stack)
						propertyPath = 'rootObject.' + prop
					else
						propertyPath = stack + '.' + prop;
					getProp(o[prop], propertyPath);
				} else {
					propertyPath = stack + '.' + prop;
					document.write('<span style="color:red">Циклическая ссылка. Свойство: ' + propertyPath+'</span><br>');
				}
				delete o[prop][handledFlag]
            } else {
                document.write('Finite value: '+o[prop]+'<br>')
            }
        }
    }
}