I know this sounds silly, but now my curiosity has me stuck on this idea. Is it possible to declare a collection of key/value pairs, like var collection = {a:"1", b:"2"}
and then have a third pair saying c: "3" + b.value?
-
1See this question http://stackoverflow.com/questions/4616202/self-references-in-object-literal-declarations – Nenad Vracar May 02 '17 at 13:33
5 Answers
First way, using a property getter
.
Please note c
is a property as b
and c
.
var collection = {
a: 1,
b: 2,
get c() {
return this.a + this.b;
}
};
console.log(collection.a); // 1
console.log(collection.b); // 2
console.log(collection.c); // 3
Second way, using concise method in ES6 or a more "classical" function declaration in ES5.
Please note c
is now a function.
let collection = {
a: 1,
b: 2,
c() {
return this.a + this.b;
}
};
console.log(collection.a); // 1
console.log(collection.b); // 2
console.log(collection.c()); // 3 called as a function
Third way, using a dedicated function for initialization.
This is useful if you have a more complex initialization, maybe on more properties, and could work similarly as a "constructor".
var collection = {
a: 1,
b: 2,
c: 3,
init: function() {
this.c = this.a + this.b;
}
};
collection.init();
console.log(collection.a); // 1
console.log(collection.b); // 2
console.log(collection.c); // 3
Forth way, directly on c
property.
var collection = {
a: 1,
b: 2,
c: undefined
};
collection.c = collection.a + collection.b;
console.log(collection.a); // 1
console.log(collection.b); // 2
console.log(collection.c); // 3
Regarding specifically your question, I would solve it using a getter
and appending value "3" in front of b
(please note result is of type string), example:
var collection = {
a: 1,
b: 2,
get c() {
return '3' + this.b;
}
};
console.log(collection.a); //1
console.log(collection.b); //2
console.log(collection.c); //"32"
console.log(typeof collection.c); // string

- 71,848
- 143
- 435
- 658
-
2This is a great answer, way more through than mine. @Andrew you should accept this. – Martha May 02 '17 at 13:59
-
2
-
-
-
You can't do anything like this:
var collection = {
a: 1,
b: 2,
c: a + b
}
But you can do this:
var collection = {
a: 1,
b: 2
}
collection.c = collection.a + collection.b;

- 178
- 1
- 11
Yes, you can store functions in JavaScript objects:
var collection = {a:"1", b:"2"}
var newObj = {c: function(){
return "3" + collection.b
}
}
console.log( newObj.c() );

- 34,845
- 8
- 116
- 142
c: "3" + b
Its not performing the same object .so You need insert the key and value in to the object .declare the c
value from outer of the object
var collection = {
a: "1",
b: "2",
}
collection['c'] = '3'+collection.b
console.log(collection)

- 22,145
- 4
- 29
- 53
-
it can also work without using bracket notation `collection['c'] = ...` example: `collection.c = '3'+collection.b` – GibboK May 02 '17 at 14:14
-
1
-
Yes, I think bracket notation is more appropriate when creating "dynamic" property name on an object. But I think it is good you mentioned as could be instructive for the readers. Thanks :) – GibboK May 02 '17 at 14:22
You can't really pass "references" that get evaluated like that. Expressions are evaluated before assignment.
let obj = {
a: 1,
b: 2
};
obj.c = 3 + obj.b;
console.log(obj.c);
> 5
obj.b = 10;
console.log(obj.c);
> 5
If you really wanted to do something like that, you can create a new type of object with a form of lazy evaluation.
function Lazy(value) {
this.value = value;
}
Lazy.prototype.valueOf = function() {
if (typeof this.value === 'function') {
return this.value();
}
return this.value;
};
Lazy.prototype.toString = function() {
return this.valueOf() + "";
}
/* Then you can do this.. */
let obj = {
a: new Lazy(1),
b: new Lazy(2)
};
/* We have to defer the evaluation of the expression. */
obj.c = new Lazy(() => 3 + obj.b);
console.log(obj.c.toString());
obj.b = 10;
console.log(obj.c.toString());

- 3,479
- 2
- 18
- 40
-
-
@Radex To override toString and more importantly valueOf, so it's more like a "type" – noahnu May 02 '17 at 21:08