Search code examples
javascriptjavascript-objects

Javascript: loops structure object? and what situation use this?


Why didn't i report an error when i ran following javaScript code.

var t = { r: 2};
var c = {};
c.y = t.r = t;

console.log(t);
console.log(c);

And what scenario would use c.y = t.r = t? Thanks~

  1. Can we usage of loops structure object? Why not report error?
  2. What scenario would use a loops structure object?

Solution

  • Let's break this down into individual statements. First, you need to know that the assignments are done so that you always evaluate the things on the right side, then put them into the left side.

    E.g. var x = 1 + 2 means "add 1 and 2 together. then put the value in x".

    Step one:

    var t = { r: 2};
    

    If we're evaluating the right side of the assignment first, it means you first create an object, { r :2 }. You then "put this object into t", or assign a reference to this object to variable t:

    Next step, similar. Now you create another object. You assign it's reference to c.

    var c = {};
    

    All cool so far. Now the next line of code is a trickster:

    c.y = t.r = t;
    

    Let's break it down. Remember about evaluating right side first? But the code is read left to right? Means, we first evaluate t.r = t, then put the result into c.y.

    So let's evaluate t.r = t first. It means _put the value of t into t.r. And the value of t, as we said in the beginning, is a reference to some object.

    So the result of the evaluation is a pointer to an object. We put that pointer to an object into r property of object t. Oh, by the way, the object we're pointing to is t itself - but it doesn't matter.

    What we end up with is an object with one property, r. And the property holds a pointer to itself.

    Got the tricky part? No? Not Ask for more explanation in comments, I could go a bit deeper here.

    Now the last part is, we said that we're putting the result of evaluating t.r = t - the result of which is, if you remember, an object with a property pointing to itself - we're putting that resulting object into c.y.

    So we end up with a circular structure:

    1. c is an object
    2. c has a property y
    3. y holds a pointer to t
    4. t is an object
    5. t has a property r
    6. r also points to t above (step 4)

      console.log(t); console.log(c);


    Edit: answering questions (they were added after I've started with my answer).

    1. Can we use a circular reference object? Why no error?
    

    I guess it's obvious that yes, it's legal in JavaScript to use circular references. Object properties can point to the objects themselves. The fact that it can be dangerous doesn't prevent you from doing this.

    2. In which scenario would we use circular references?
    

    This is generally considered a bad practice. However, there are some exceptions to the rule. One example would be parent-child relations - a child object can sometimes need properties of the parent, so having a reference to it would be helpful. Or in some cases, you may use it in closures to get around non-trivial wraping of object references.

    Or similar cases with libraries that are internal to a given module.

    The problems such as strong coupling, breaking of e.g. JSON serializers etc remain, so it's often simpler to just do things "properly" and without circular references.