views:

66

answers:

4

Can someone please help me understand the scoop of JavaScript variables, and how to reach them?

Imagine the following...

// Namespace declaration
var p = {};

p.result = {

    searchForm: $('#search-form'),
    searchAction: this.searchForm.attr('action'),

    anotherSection: {
        hello: 'Hello ',
        world: this.hello + 'world!'
    }

}

This won't work, and it gives the error saying this.searchForm is undefined. The same error appears in anotherSection as well (ofc).

How can I declare a variable in terms of another variable inside the same namespace?

+3  A: 

The this keyword is bound to the function-context, you can't use it in object literals like that.

You could, make functions as "getters":

var p = {};
p.result = {
  searchForm: $('#search-form'),
  getSearchAction: function () {
    return this.searchForm.attr('action');
  },
  anotherSection: {
    hello: 'Hello ',
    getWorld: function () {
      return this.hello + 'world!';
    }
  }
};
CMS
+1 for the edit and code example. I think this looks like a good solution :)
Mickel
You could optimize it using `this.getWorld = this.hello + 'world!'; return this.getWorld` so that it only concatenates the string the first time it gets called.
Etan
A: 

this is an object, so when you use this.searchForm, you are accessing a property of the this object. You just want to access a variable, so you can just use searchForm.

Josh Yeager
I've already tried that and it does not work.
Mickel
+3  A: 

There is no way to refer to an object literal as you're building it.

You need to write the following:

p.result = {
    searchForm: $('#search-form'),
    anotherSection: {
        hello: 'Hello '
    }
}

p.result.searchAction = p.result.searchForm.attr('action');
p.result.anotherSection.world = p.result.anotherSection.hello + 'world!';
SLaks
+1 thanks, but I'll go for the solution provided by CMS this time.
Mickel
A: 

You can't access the properties of an object inside its own literal — they don't exist yet.

David Dorward