19

Possible Duplicate:
Self-references in object literals / initializers

Can this be done? (obviously not in this syntax)

var a = {
    b : 10,
    c : this.b * 2 // returns 'undefined'
};

I have also tried

var a = {
    b : 10,
    c : a.b * 2 // throws error 'a is undefined'
};

and

var a = {
    b : 10,
    c : b * 2 // throws error 'b is undefined'
};

It makes sense to me that these values are undefined, I have not finished defining them. However it seems to me like there would be a solution to structuring a object like that and having c be conditional on b

Cœur
  • 37,241
  • 25
  • 195
  • 267
rlemon
  • 17,518
  • 14
  • 92
  • 123
  • Considering you are initializing `b` at compile time, why would `c` be conditional on it? You already know what it is! – Chad La Guardia Sep 15 '11 at 15:30
  • 1
    What I have posted is a simplified example. I will not always know what `b` is. Otherwise I wouldn't need to have it conditional. think `b : function(x) { /* do some stuff */ return y;},` – rlemon Sep 15 '11 at 15:32
  • 1
    @Chad 1. JS isn't compiled, 2. it's perfectly normal to initialise a variable with an expression based on another, and other languages (e.g. C) manage it perfectly well. – Alnitak Sep 15 '11 at 15:32
  • @Alnitak compiled is the wrong word for JS... but my point is the same. He is hardcoding a value (equivalent to knowing something at compile time). However, the OP has clarified that he may not actually know the value, so the point is moot anyway. – Chad La Guardia Sep 15 '11 at 15:33
  • thankyou @Felix Kling! I couldn't find any posts on this when I first searched it. I like the getters solution. +1 – rlemon Sep 15 '11 at 15:35
  • You're welcome :) (I only found it because knew I answered something like this ;)) – Felix Kling Sep 15 '11 at 15:36
  • for this question, setting the getter should be the answer. It's the most elegant and straightforward solution. Shame that it can't be posted as an answer now. Once a question is marked as duplicate, no new answer can be posted right? – nxmohamad Nov 07 '17 at 07:02

2 Answers2

15

Alternatively, you can use a self starting function to give you a similar affect to what you are looking for:

var a = (function() {
    var b = 10;
    return {
        b:b,
        c:b*2
    }
})();

console.log(a.c);
Skylar Anderson
  • 5,643
  • 1
  • 25
  • 34
  • 3
    I like that, seems almost *hacky* – rlemon Sep 15 '11 at 15:42
  • 1
    @rlemon: if you like that, why don't you just do it in two parts to void yourself of the function overhead? In fact, this is clutter. It is still doing everything in two steps and on top of that, you're calling an unnecessary function. – vol7ron Dec 01 '12 at 14:55
1

Not using object literal notation, but you can use functions to create it:

function Structure(value) {
    this.b = value;
    this.c = 2 * value;
}

var a = new Structure(10);

or

function makeStructure(value) {
    return {b:value, c:2*value};
}

var a = makeStructure(10);
Dennis
  • 32,200
  • 11
  • 64
  • 79