4

I'm trying this

var a = {
    "a" : "Hey",
    "b" : this.a + "!"
};

console.log(a.b);

==>"undefined!"

but if I use this it works fine.

var a = {};
a.a = "haha";
a.b = a.a + "!";

console.log(a.b);

==>"haha!" 

How can I use the first way to make it work?

  • 1
    There's no way to point to the in construction object literal. You have to change the first way so that it is,like the second one. If that doesn't suit you, what are your precise requirements ? – Denys Séguret Jul 02 '13 at 07:49
  • 1
    Welcome to SO! This question has been asked (and answered) before, see http://stackoverflow.com/questions/4616202/self-references-in-object-literal-declarations – georg Jul 02 '13 at 07:49

3 Answers3

6

this doesnt exist in that context of an Object literal. You will have to write a.a instead of this.a. However, while inside a function which is defined in the object, this actually refers to the object itself.

This has to do with JavaScripts referencing environments.

Eric
  • 18,532
  • 2
  • 34
  • 39
  • 1
    `this` *does* exist, but it does not refer to the object. Neither will `a` though *at that moment* (if you suggest to use `"b" : a.a + "!"`, it's not really clear from your answer). – Felix Kling Jul 02 '13 at 08:03
5

You can't.

This is just how the literal object declaration is designed in JavaScript; no self referencing will work

All references to this are resolved based on the scope in which the code is running, defaulting to window if you're in the global scope.

Update

Without resorting to the new getters and setters syntax, you can do two things:

  1. Build the object but leave out the properties that have self references; afterwards, append them. This is what you did as well.

  2. Turn a property into a function instead:

    var a = {
        "a" : "Hey",
        "b" : function() { return this.a + "!"; }
    };
    
    console.log(a.b()); // "Hey!"
    

Be careful with this approach, because changing the value of a.a will also affect the output of a.b().

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Actually the self referencing part is not entirely true - if you declare a function on the object and call it, `this` would actually refer to the object. Also ES5 has setters and getters (like i stated in my answer) to achieve that. – Christoph Jul 02 '13 at 08:13
  • @Christoph: This answer does not deny that AFAICS. It just says that there is no syntactic construct to refer to an existing property in an object *literal*. You are talking about run time behavior. – Felix Kling Jul 02 '13 at 08:17
  • @Christoph Yes, like I said, references to `this` are resolved based on the scope; in the case of a function call on an object, the scope is the object itself (assuming the function is either explicitly or implicitly bound to it). – Ja͢ck Jul 02 '13 at 08:21
2

Ecmascript edition 5 introduces some nice addition to objects: Setters and getters. In modern browsers, you can use the getter method to achieve the result you need:

var a = {
    "a" : "Hey",
    get b(){ return this.a + "!" },
    set c(x){ this.a = x}
};

Now a.b will give you the correct result Hey!.

The setter function for c would cause a normal assignment a.c = "foo" to actually set a.a to foo!

Christoph
  • 50,121
  • 21
  • 99
  • 128