68

I am trying to do something like this:

var obj = { a: 5, b: this.a + 1 } 

(instead of 5 there is a function which I don't want to execute twice that returns a number)

I can rewrite it to assign obj.b later from obj.a, but can I do it right away during declaration?

2

7 Answers 7

51

No. this in JavaScript does not work like you think it does. this in this case refers to the global object.

There are only 3 cases in which the value this gets set:

The Function Case

foo(); 

Here this will refer to the global object.

The Method Case

test.foo(); 

In this example this will refer to test.

The Constructor Case

new foo(); 

A function call that's preceded by the new keyword acts as a constructor. Inside the function this will refer to a newly created Object.

Everywhere else, this refers to the global object.

Sign up to request clarification or add additional context in comments.

7 Comments

+1 Nice answer. Only I'd add the case when this is set explicitly using the function or method case via .call() or .apply(). (Perhaps more of a subset of those two cases.)
Yes, those could be added, but they are a bit out of scope here IMO, although I'll add them to my docs.
I agree. I think your answer covers the necessary bases for the question.
@user113716 Don't forget .bind(...)
this in "The Function Case" refer to the parent object, not the global object: const obj = { a: 5, b: function foo() { return this.a + 1; } };
|
14

There are several ways to accomplish this; this is what I would use:

function Obj() { this.a = 5; this.b = this.a + 1; // return this; // commented out because this happens automatically } var o = new Obj(); o.b; // === 6 

Comments

9

This should return the correct values:

function () { var aVar = 5; var bVar = aVar + 1; return { a : aVar, b : bVar; } }(); 

Comments

5

As it turns out you can't reference an object inside another object unless the first one is a function. But you can do it this way.

 var obj = { a: 5 } obj.b = obj.a + 1; // create field b in runtime and assign it's value 

If you console.log(obj) you will have

 obj = { a: 5, b: 6 } 

This way you keep the object literal structure for the remaining part of the code

Comments

2

No, in your example, the value of this doesn't refer to the object literal.

You'll need to assign a value to b after the object has been created in order to base it on another property in obj.

Comments

2

No. this will take the same meaning as it would outside the definition.

Comments

2

in chrome debugger

> var o = {a: 5, b: this.a+1} undefined > o.b NaN > o.a 5 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.