0

Is there a way of accomplishing

{foo: parseFloat("5.5"), bar: foo + 5}

without having to define the value of foo before evaluating the object literal?

EDIT: Sorry that I didn't make that more clear, but I wanted to define foo in-place and then reference it's value from within bars value definition.

chris.js
  • 11
  • 2
  • 1
    Nope, there is not! There are workarounds, like using functions etc instead, depending on what exactly you're trying to do. – adeneo Dec 25 '14 at 00:10
  • Note that this design can usually be avoided. Transitive dependencies between properties can cause anomalies and memory consumption. For example, you might want to use an object prototype with a function instead of an additional static property. – Tobias Dec 25 '14 at 00:19
  • 1
    Why do you use `parseFloat` on an already numeric string? Unary `+` operator is shorter and faster: `+"5.5"`. – Oriol Dec 25 '14 at 00:21
  • Sorry Oriol, parseFloat was just a placeholder for a computation. But thanks a lot still, as I didn't know that either. :) – chris.js Dec 25 '14 at 00:46

2 Answers2

2

No. There is no way of accessing properties of a literals inside that literals declaration.

You could, if you feel you need the functionality, write a function that will create objects for you in a way as to accomplish what you are looking for in a single line of code, but really i'd suggest you just use the two lines it take to write

var foo = parseFloat("5.5");
var baz = { foo: foo, bar: foo + 5 };

instead of building abstractions you don't really need.

Martin Jespersen
  • 25,743
  • 8
  • 56
  • 68
0

Use the "secret" ES5 getter syntax to perform inline calculations using this to refer to the literal:

JSON.stringify({
  foo: parseFloat("5.5"), 
  get bar(){return this.foo + 5}
});

// == "{"foo":5.5,"bar":10.5}"

note that the binding is live, so if you update foo, then bar will start equating to the new value + 5.

also not that the word "function" in the "method" is spelled "get", that's no typo, just ES5 awesomesause. it would be nice if you could use some kind of "fat arrow" in there, but i don't know if/when that will ever happen. to make the property value truly static, which might save ram on large sets, you can add a bit more ugliness and minor repetition:

ob=  {
      foo: parseFloat("5.5"), 
      get bar(){  delete this.bar; return this.bar=this.foo + 5; }
    };
JSON.stringify(ob); // == "{"foo":5.5,"bar":10.5}"

it's what you need to get the value mid-literal, and a little more (live updates), hopefully that's not too much for your project. i find it cleaner than an off-side temp var if you don't NEED it to be static.

note: this trick works on IE9 and newer browsers; use a temp variable for legacy compat.

dandavis
  • 16,370
  • 5
  • 40
  • 36