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!
var obj = { key1: #1= (new String("it ")), key2: #1# + "works!" }; alert(obj.key2)