How can a Javascript object refer to values in itself? [duplicate]

Lets say I have the following javascript:

var obj = {
 key1 : "it ",
 key2 : key1 + " works!"
};
alert(obj.key2);

This errors with "key1 is not defined". I have tried

this.key1
this[key1]
obj.key1
obj[key1]
this["key1"]
obj["key1"]

and they never seem to be defined.

How can I get key2 to refer to key1's value?

Answers:

Answer

Maybe you can think about removing the attribute to a function. I mean something like this:

var obj = {
  key1: "it ",
  key2: function() {
    return this.key1 + " works!";
  }
};

alert(obj.key2());

Answer

This can be achieved by using constructor function instead of literal

var o = new function() {
  this.foo = "it";
  this.bar = this.foo + " works"
}

alert(o.bar)
Answer

You can't refer to a property of an object before you have initialized that object; use an external variable.

var key1 = "it";
var obj = {
  key1 : key1,
  key2 : key1 + " works!"
};

Also, this is not a "JSON object"; it is a Javascript object. JSON is a method of representing an object with a string (which happens to be valid Javascript code).

Answer

One alternative would be to use a getter/setter methods.

For instance, if you only care about reading the calculated value:

var book  = {}

Object.defineProperties(book,{
    key1: { value: "it", enumerable: true },
    key2: {
        enumerable: true,
        get: function(){
            return this.key1 + " works!";
        }
    }
});

console.log(book.key2); //prints "it works!"

The above code, though, won't let you define another value for key2.

So, the things become a bit more complicated if you would like to also redefine the value of key2. It will always be a calculated value. Most likely that's what you want.

However, if you would like to be able to redefine the value of key2, then you will need a place to cache its value independently of the calculation.

Somewhat like this:

var book  = { _key2: " works!" }

Object.defineProperties(book,{
    key1: { value: "it", enumerable: true},
    _key2: { enumerable: false},
    key2: {
        enumerable: true,
        get: function(){
            return this.key1 + this._key2;
        },
        set: function(newValue){
            this._key2 = newValue;
        }
    }
});

console.log(book.key2); //it works!

book.key2 = " doesn't work!";
console.log(book.key2); //it doesn't work!

for(var key in book){
    //prints both key1 and key2, but not _key2
    console.log(key + ":" + book[key]); 
}

Another interesting alternative is to use a self-initializing object:

var obj = ({
  x: "it",
  init: function(){
    this.y = this.x + " works!";
    return this;
  }
}).init();

console.log(obj.y); //it works!
Answer

Because the statement defining obj hasn't finished, key1 doesn't exist yet. Consider this solution:

var obj = { key1: "it" };
obj.key2 = obj.key1 + ' ' + 'works!';
// obj.key2 is now 'it works!'
Answer

That's not a JSON object, that's a Javascript object created via object literal notation. (JSON is a textual notation for data exchange (more). If you're dealing with JavaScript source code, and not dealing with a string, you're not dealing with JSON.)

There's no way within the object initializer to refer to another key of the object being initialized, because there's no way to get a reference to the object being created until the initializer is finished. (There's no keyword akin to this or something for this situation.)

Answer

You can also reference the obj once you are inside the function instead of this.

var obj = {
    key1: "it",
    key2: function(){return obj.key1 + " works!"}
};
alert(obj.key2());
Answer

This is not JSON. JSON was designed to be simple; allowing arbitrary expressions is not simple.

In full JavaScript, I don't think you can do this directly. You cannot refer to this until the object called obj is fully constructed. So you need a workaround, that someone with more JavaScript-fu than I will provide.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.