How to find the circular structure in JSON.stringify: Uncaught TypeError: Converting circular structure to JSON?

StackOverflow https://stackoverflow.com/questions/20953383

When I get Uncaught TypeError: Converting circular structure to JSON on a large structure it can be very difficult to find out where exactly the circular reference is.

Is there a simple way to find/debug the circular element in the data structure?

有帮助吗?

解决方案

I haven't found a simple method to do it, other people seem to be suggesting using custom replacer function in JSON.stringify to control which properties have been visited.

I've attempted to write such replacer:

function detector(obj) {
    function collector (stack, key, val) {
        var idx = stack[stack.length - 1].indexOf(key);

        try {
            var props = Object.keys(val);
            if (!props.length) throw props;
            props.unshift({idx : idx});
            stack.push(props);
        } catch (e) {
            while (!(stack[stack.length - 1].length - 2)) {
                idx = stack[stack.length -1][0].idx;
                stack.pop();
            }

            if (idx + 1) {
                stack[stack.length - 1].splice(idx, 1);
            }
        }

        return val;
    }

    var stack = [[]];

    try {
        JSON.stringify(obj, collector.bind(null, stack));
    } catch (e) {
        if (e.message.indexOf('circular') !== -1) {
            var idx = 0;
            var path = '';
            var parentProp = '';
            while(idx + 1) {
                idx = stack.pop()[0].idx;
                parentProp = stack[stack.length - 1][idx];
                if (!parentProp) break;
                path = '.' + parentProp + path;
            }

            console.log(path);
        }
    }
}

What it does is while traversing the JSON tree (probably tree :)) it collects names of properties which have been visited and as soon as JSON.stringify detects circular reference and throws, 'stack' variable will contain a trace of which subtree it was traversing. And it logs this path to console.

However, this is not a heavily tested solution.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top