1

I do:

outerobject={
    a: 1,
    b: 2,
    c: this.a + this.b,
};

console.log(outerobject.a);
console.log(outerobject.b);
console.log(outerobject.c);

I expect:

1
2
3

I get:

1
2
NaN

Why do I get a NaN?

Breako Breako
  • 6,353
  • 14
  • 40
  • 59
  • 1
    Because `this` isn't `outerobject`. Add `"use strict";` at the top of your code and you'll get a nice error message instead of a silent failure: `TypeError: Cannot read property 'a' of undefined`. – Blender Dec 11 '13 at 17:27
  • See [this](http://stackoverflow.com/questions/1403029/order-of-attribute-evaluation-in-javascript-object-literals). – Joe Enos Dec 11 '13 at 17:28
  • @Blender: There won't be an error in strict mode if the code is running globally, or in a function that has its `this` set. – Blue Skies Dec 11 '13 at 17:30

3 Answers3

3

Within the object this is assigned a reference to the window or the global object. You need to use a function which will have this refer to a reference of the object.

var outerobject={ a: 1, b: 2, c: function(){return this.a + this.b}};
var outerobject2={ a: 1, b: 2, c: console.log(this)}; //logs window/global object

console.log(outerobject.c());//outputs 3

or use a function constructor:

function MyObject(){
    this.a = 1;
    this.b = 2;
    this.c = this.a + this.b;
    console.log(this);
}

var myObject = new MyObject();

The key is the function determines the scope of this. When a function is called as a method of an object, its this is set to the object the method is called on.

JS Fiddle: http://jsfiddle.net/aRFLn/

Read More

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • The explanation is correct, but I wouldn't use the suggested solutions. Using a method requires a different syntax to be called (btw, should be called `getC()`) and property created inside a constructor won't update it's value as someone may expect. – Pavlo Dec 11 '13 at 17:48
  • @Pavlo Good point about the function constructor, I guess that wouldn't work so well if the object changes – Kevin Bowersox Dec 11 '13 at 17:51
  • 1
    All depends on if OP intends for it just in initialization or in every access of that property. Not much context was given in the question. – Blue Skies Dec 11 '13 at 17:52
1

You probably want to get the sum of property values a and b. You'll need a getter for this:

var outerobject = {
    a: 1, // inside a property value `this` is `window`
    b: 2,
    get c() {
        return this.a + this.b; // inside a getter function 'this' is `outerobject`
    }
};

Then you can use outerobject.c. It will also be re-evaluated each time you call it:

outerobject.c; // 3
outerobject.a++;
outeobject.c; // 4
Pavlo
  • 43,301
  • 14
  • 77
  • 113
0

In your case 'this' could be any number of things depending on where this is being called. In your case it most likely is the window object. Since window probably doesn't have a and b defined so you get NaN.

Here's a good example on how this works: http://www.quirksmode.org/js/this.html

Esteban Felix
  • 1,561
  • 10
  • 21