0

Well, the question may be not good formulated, but I'll try to get it more clear by example:

var test = {
            x1 : 10,
            x2 : 20,
            x3 : x1 + 5,
            x4 : x2 + 5,
        }

What I need, is refer to "x1" or "x2" field, which was previously declared. But, if I wrote like in example, JS says, that "x1 is not defined".
My second try was:

var test = {
            x1 : 10,
            x2 : 20,
            x3 : this.x1 + 5,
            x4 : this.x2 + 5,
        }

But "x3" and "x4" become "NaN", because "this.x1", and "this.x2" is "undefined".
I even tried:

var test = {
            x1 : 10,
            x2 : 20,
            x3 : test.x1,
            x4 : test.x2,
        }

But get "test is undefined". So, how can i refer, to "x1" or "x2"?
P.S. I know, that I can write something like:

var test2 = new (function(){
        this.x1 = 10;
        this.x2 = 20;
        this.x3 = this.x1 + 5;
        this.x4 = this.x2 + 5;
    })();

And it will work just fine, but I really need a JSON-like object definition.

Update: I forgot that this description of object is called a "literal". Because of that I couldn't find existing questions about this theme. However, now I've read similar questions and answers for them, and have not found answer, that solve my problem.
In fact I need to remain in literals notation, because I am developing a "configuration file format", that must have a declarative syntax (and parser for this format of course, that will execute some algorithm according to this configuration file). And this configuration file must be understandable and editable by people, who don't understand JS. For them it's not a script, or object, but just a JSON with specified structure. So I can't use some init function in the end.
Even getters will add too many complexity. It may sound funny, but yes, it's too complex. It will add keywords "get", and "return", and also round brackets and semicolon punctuation. When JSON syntax have only two type of brackets and two type of punctuation: colon and comma. So the complexity almost doubled with getters or functions, even if they would be consists of only one string.
For now I'm leaning towards option, just to add the "id" field, and referenced by it. But maybe someone could offer a better solution.

P.S. I dont have any option other than use some valid JS for this configuration file, because my application would not have any server side. Only local JS and HTML file, and only standard browser for run them, so no file access. Because of that configuration file will be provided to application in form of JS file.

Vladimir Liubimov
  • 964
  • 1
  • 11
  • 16
  • 1
    Possible duplicate of [Self-references in object literal declarations](http://stackoverflow.com/questions/4616202/self-references-in-object-literal-declarations) – JJJ Jan 28 '16 at 08:35
  • some preprocessing should be necessary: one possible solution could be a string with the value to be calculated, like `x3 : 'this.x1 + 5',` eval could be performed and the result assigned. – Nina Scholz Jan 28 '16 at 14:06
  • Eval is probably the *worst* solution to the problem. Why not just `test.x3 = test.x1 + 5` after the initial definition? – JJJ Jan 28 '16 at 14:21
  • For now I've decided to solve my problem, by decomposition of my literal into several pieces. So users can refer to field, defined in one literal, from another literal. They can't refer to any possible field, but they at least can declare some "library" with elements to reuse. That should be enough. Maybe it even better, than grant them power to refer everything. In other words it'll make configuration format more strict. Example: `var base = { x1 : 10, x2 : 20 }; var test = { x1 : base.x1, x2 : base.x2, x3 : base.x1 + 5, x4 : base.x2 + 5, };` – Vladimir Liubimov Jan 29 '16 at 06:04

2 Answers2

1

Maybe you use a get syntax:

var test = {
    x1: 10,
    x2: 20,
    get x3() { return this.x1 + 5; },
    get x4() { return this.x2 + 5; }
}

document.write(test.x3);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Someone doesn't like this question *alot* probably – Idos Jan 28 '16 at 08:45
  • I completely agree. As you can see I got downvoted as well, atleast you got re-voted... :/ – Idos Jan 28 '16 at 08:52
  • Not my downvote, but this doesn't do what the OP describes in the question. The getter returns the value dynamically based on the other values instead of initializing it. – JJJ Jan 28 '16 at 08:59
  • but json like is missleading. json's does not have functionality. and are strings. – Nina Scholz Jan 28 '16 at 09:01
  • Thank you for answer. I did not knew about getters. It seems to be relatively new feature (I've studied JS a long ago). Since I use canvas anyway, it doesn't matter, that getters not supported by the old browsers. Returning of dynamic value is not a problem for my case. This object must be constant anyway. On the other hand I try to avoid imperative JS syntax (which used inside getters), and use only JSON syntax. It must be a something like "configuration file" for the rest of algorithm, and this "file" will be edited by not js programmer. Maybe even not by programmer at all. – Vladimir Liubimov Jan 28 '16 at 11:58
  • So the main goal here, to make syntax as easy and declarative as possible. So I've hoped, that for literals exists some analog for "this", allowed for use inside literal. In any case getters syntax seems to be more easy than function. I would think about using it. Or maybe just will use some "id field" for internal referencing, and then build another object with real references and other stuff, based on this JSON structure. P.S. I forgot that this description of object is called a "literal". So I couldn't find existing questions about this theme. Now I see, that here a lot of them. My bad. – Vladimir Liubimov Jan 28 '16 at 12:00
  • the problem with `this` is, the time. at the moment, where the object literal is read/evaluated, `this` is not available, because the object does not yet exist, like your test with `x3 : test.x1,` even the `test` does not exist at this time. but the main question is, for which purpose is the object? – Nina Scholz Jan 28 '16 at 12:09
  • Yes, I've already understand, that object creates only after definition of the literal is finish. Before, I thought, that var a = {x:10} is equvivalent to var a = {}; a.x=10; Live and learn. I've added more details to the question, so it would be more clear, what is the problem I'm trying to solve. – Vladimir Liubimov Jan 28 '16 at 13:44
-1

You should do like this:

var test = {
    x1 : 10,
    x2 : 20,
    x3 : function() {
        return this.x1 + 5;
    },
    x4 : function() {
        return this.x2 + 5;
    },
}
alert(test.x3())

Another way to acheive this (more oop):

var test = function() {
    var self = this;
    self.x1 = 10;
    self.x2 = 20;
    self.x3 = self.x1*2;
    self.x4 = self.x2*2;
}

var toto = new test();
alert(toto.x3);
ADreNaLiNe-DJ
  • 4,787
  • 3
  • 26
  • 35