Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to test circular reference in JavaScript?

I'm making a game, and I've come across a problem... When I try to save, JSON fails and reports that circular reference is being made somewhere. I don't think it actually is, I can't see it, so is there an algorithm or anything which could tell me where it is exactly (between which objects and stuff)? Also, is there a JSON alternative that can save circular reference? I'm running a node.js server, I saw this, but I can't get it to work (it's not made as a module i can require() in my code).

like image 318
corazza Avatar asked Sep 28 '11 10:09

corazza


People also ask

How do you find circular dependency?

By running a cli command npx madge --circular --extensions ts ./ we can quickly get a list of circular dependencies of all . ts files in current directory and its subdirectories.

What is wrong with circular references?

The circular reference error message "There are one or more circular references where a formula refers to its own cell either directly or indirectly. This might cause them to calculate incorrectly. Try removing or changing these references, or moving the formulas to different cells."

What is circular reference in JavaScript?

A circular reference occurs if two separate objects pass references to each other. In older browsers circular references were a cause of memory leaks. With improvements in Garbage collection algorithms, which can now handle cycles and cyclic dependencies fine, this is no longer an issue.

Are circular references bad JavaScript?

It will not be a problem for garbage collection: any new Garbage Collector (>IE6) will handle circular references just fine! It might be a problem though if you are doing recursive functions, or printing the object. So the answer is: it is no problem unless you screw up yourselves :-) Show activity on this post.


1 Answers

This is a small extension to Andris' answer that tells you where the first circular element is so you can deal with it accordingly.

function findCircularObject(node, parents, tree){
    parents = parents || [];
    tree = tree || [];

    if (!node || typeof node != "object")
        return false;

    var keys = Object.keys(node), i, value;

    parents.push(node); // add self to current path
    for (i = keys.length - 1; i >= 0; i--){
        value = node[keys[i]];
        if (value && typeof value == "object") {
            tree.push(keys[i]);
            if (parents.indexOf(value) >= 0)
                return true;
            // check child nodes
            if (arguments.callee(value, parents, tree))
                return tree.join('.');
            tree.pop();
        }
    }
    parents.pop();
    return false;
}

If you don't want a string, the tree array is unnecessary. Just change the original function to

return value;

for the circular object itself or

return parents.pop();

for its parent.

like image 180
jimmetry Avatar answered Sep 22 '22 04:09

jimmetry