views:

117

answers:

2

so I have an object definition that looks like this:

var Foo = window.Foo = {
  MIN_ROWS : 10,
  MIN_COLS : 10,

  NUM_ROWS : (function(){ return Math.max( parseInt(this.params.rows) || 0, this.MIN_ROWS); })(),

  // etc...

  params: (function(){ /* ... */ })() // parses the GET querystring parameters from the URL and returns as a JSON object

}

For the NUM_ROWS property, I want to set it to be Foo.params.rows if it exists and it's greater than MIN_ROWS, otherwise set it to MIN_ROWS.

I've already figured out the logic for this, the only thing that's giving me trouble is when I self-invoke the function as above, the this variable refers to window and not to Foo as I would expect it to. (This is the error message I get in the console: "TypeError: Result of expression 'this.params' [undefined] is not an object." )

If I don't self-invoke the function, it works perfectly. However, I'd like to have NUM_ROWS be an integer, not a function, so that I can access it as Foo.NUM_ROWS and not Foo.NUM_ROWS() in the other parts of my code.

Can anyone help me out with this please?

+1  A: 

Here's how I fixed it, I simplified the code a bit, but you should get the idea, if you haven't already, hope it helps. The link below is definately worth following if you're into getting your javascript nailed.

var FooFactory = function(){
  this.MIN_ROWS = 10;
  this.MIN_COLS = 10;
  this.params = { rows : 12};

  this.NUM_ROWS = Math.max( parseInt(this.params.rows) || 0, this.MIN_ROWS);
  // etc...
};
var Foo = window.Foo = new FooFactory();

document.write(Foo.NUM_ROWS);

this in JavaScript is the object that is calling, not the the object being called, you need to look at Doug Crockford's site to get some good articles on what this means, and how it affects your usage in this case.

This article in particular shows you what this is all about

Mark Dickinson
A: 

why don't you initialize params before NUM_ROWS? params is not available yet at the time ...

other than that, you might wanna declare a getter ...


edit: well, in that case, a getter is really a good option ... won't work to well in IE though ... apart from that, you can always build the object step by step ...

var Foo = window.Foo = {
  MIN_ROWS : 10,
  MIN_COLS : 10
}
Foo.params = //parse input
Foo.NUM_ROWS = Math.max( parseInt(Foo.params.rows) || 0, Foo.MIN_ROWS));

or maybe this way:

var params = //parse input
var NUM_ROWS = Math.max( parseInt(params.rows) || 0, this.MIN_ROWS));
var Foo = window.Foo = {
  MIN_ROWS : 10,
  MIN_COLS : 10
  params: params,
  NUM_ROWS: NUM_ROWS
}

yes, it's not so funky as what you tried to use, but it simply works ... plus it saves you at least one call ...


back2dos
Thanks for the response, but unfortunately this doesn't seem to solve anything. Please see my comment above.
gabriel