-2

Consider:

var s1 = {
    a: 1,
    b: s1.a    
};    

alert(s1.b); // Uncaught TypeError: Cannot read property 'a' of undefined

Can anyone shed light on the inner workings of JavaScript engines to why this is the case?

Currently I'm forced to use:

var s2 = {
    a: {
        a: 1
    },
    b: {
        a: function () { return s2.a.a}
    }
};

alert(s2.b.a()); // 1
geoyws
  • 3,326
  • 3
  • 35
  • 47
  • 4
    This has nothing to do with how "engines create variables". Rather it is simply how the language works. In this case, trivially, an assignment to a variable only happens **after** the expression on the right is evaluated. (Also that will result in a different error unless `s1` has *already* been assigned. Run it again in a fresh console to track down the "core" issue.) – user2864740 Oct 12 '14 at 09:58
  • The key part is that object literal - the expression right of the assignment sign is evaluated as a whole first. And it makes a perfect sense; an object literal is, by definition, an atomic structure. – raina77ow Oct 12 '14 at 10:01
  • This question has been asked dozens of times on SO, in either this variant or the `b: this.a` variant. –  Oct 12 '14 at 12:12
  • I'm actually hoping for an answer similar to @raina77ow's comment to know the way JavaScript engines do the variable instantiation in C++... hi there again Torazaburo, I spent a little bit of time reading through your blog. ;) I'm just a young man many years your junior, starting out in programming. :) – geoyws Oct 12 '14 at 13:23

1 Answers1

1

Inside of this declaration:

var s1 = {
    a: 1,
    b: s1.a    
};  

s1 is not yet defined until the end of the data declaration, thus it cannot be referred to inside of the data declaration. This is just how Javascript works.

You could just do this instead:

var s1 = { a: 1 };  
s1.b = s1.a;
jfriend00
  • 683,504
  • 96
  • 985
  • 979