-3

I would like to know if either of these rely on undefined behaviour, and/or if they can be adapted so that they do not:

Example 1:

var str = {
  ver: '1.01',
  verdesc: 'WIP',
  composite: {
    version_block: str.ver + str.verdesc
  }
}

Example 2:

var str = {
  ver: '1.01',
  verdesc: 'WIP',
},
composite: {
  version_block: str.ver + str.verdesc
};
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Rob F
  • 529
  • 6
  • 17
  • 5
    You haven't even tried to execute that code... `:-/` – Šime Vidas Aug 08 '12 at 01:41
  • If the code ran or did not run, it does not tell me whether it is undefined behaviour. In some languages the order that expressions are evaluated can vary depending on the implementation. – Rob F Aug 08 '12 at 01:47
  • If your examples worked, both would have different values. In your first example, `composite` is a property of `str`. In your second, `composite` would be a separate variable altogether. What are you trying to accomplish? – Ian Hunter Aug 08 '12 at 01:48
  • The point is that I don't really care of composite is a separate variable or a member of str, though I'd prefer the latter. I presented the examples as a way of saying "If 1st version doesn't work, does the second?" Yes, I didn't run the code, I just typed it out now into the web form, and yes it would yield a syntax error which is an irrelevent mishap on my part, and even if I had tested it it would not have answered my question, so stop punishing me for that. – Rob F Aug 08 '12 at 01:50
  • To put it another way: are the expressions after declarations evaluated in a procedural, left-to-right order, guarranteed as per the standard? – Rob F Aug 08 '12 at 01:51
  • @Rob F: If it ran as intended, it's true that it wouldn't tell you whether it's undefined behaviour. If it didn't run as intended, it would immediately tell that it's unusable, which would render the definition question moot. Again, you should have just given it a shot. – Ates Goral Aug 08 '12 at 01:51
  • No, this is not undefined behaviour, it's pretty clearly specified that neither of those does work as you intended (evaluation order is exactly defined for JS, basically left-to-right or outside-in). Have a look at [Self-references in object literal declarations](http://stackoverflow.com/q/4616202/1048572) instead. – Bergi May 27 '15 at 17:37

2 Answers2

2

You are trying to reference a property that is defined via an object literal, from within the object literal itself. This is not possible. The properties are assigned to the str variable only after the entire object literal is evaluated. So, within the object literal, you cannot refer to properties of str.

So, when you assign an object literal to a variable,

var obj = { ... };

then, inside that object literal, you cannot use the obj reference at all. At the time the object literal is evaluated, obj is still undefined, and only after the object literal has been fully parsed and evaluated, the corresponding Object value is created, and assigned to obj.

var obj = {
    a: 123,
    b: obj.a // this will throw, "obj" is undefined
};
obj.b = obj.a; // this works
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
1

http://jsfiddle.net/kendfrey/XwVFt/

The error message explains it all.

You can't do that. The properties of the variable are not accessible until the variable is assigned, which happens after the whole object has been created.

You can work around this by assigning the object, and then setting its properties.

var str = { };
str.ver = '1.01';
str.verdesc = 'WIP';
str.composite = {
  version_block: str.ver + str.verdesc
}
Kendall Frey
  • 43,130
  • 20
  • 110
  • 148