lshettyl
lshettyl

Reputation: 8171

object oriented javascript - "this" key word and accessing functions within an object

I am, for the first time, trying some OO JS. Here is what I've come up with so far:

var myObj = {
1   site_url: window.location.protocol + "//" + window.location.hostname + "/",
2   site_host: window.location.hostname,
3   site_brand: this.readCookie('aCookieName'),
4   site_full_url: this.site_url + window.location.pathname,
5   /***
6   Read a cookie by its name;
7   **/
8
9   readCookie: function(name) {
10      var nameEQ = name + "=";
11      var ca = document.cookie.split(';');
12      for(var i=0;i < ca.length;i++) {
13          var c = ca[i];
14          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
15          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
16      }
17      return null;
18  },
19
20  /***
20  ***/
22  SaySomeThing: function() {
23      alert(this.site_brand);
24  }
}

Bear with me, I am new to this. The problem I have is:

Line # 3 - I get an error: readCookie is undefined;
Line # 4 - Another error: site_url is undefined;

Please help me with the above.

Upvotes: 4

Views: 345

Answers (5)

Martijn
Martijn

Reputation: 13622

Avoid this. You usually won’t need it, except in very specific cases. Here’s how I would write this (in a hurry):

var myObj = (function {
    /***
    Read a cookie by its name;
    ***/
    var readCookie = function(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    };
    var saySomeThing = function() {
        alert(this.site_brand);
    };

    var result = {
        site_url: window.location.protocol + "//" + window.location.hostname + "/",
        site_host: window.location.hostname
        site_brand: readCookie('aCookieName'),
        site_full_url: null, // you can't access other parts of the same object in an object literal
        saySomeThing: saySomeThing
    };
    result.site_full_url = result.site_url + window.location.pathname;

    return result;
})();

This is assuming that you won’t be needing the readCookie function from outside the myObj object, and that you do want to access saySomeThing from outside your object.

By wrapping the whole definition in an anonymous function (which gets executed immediately), you hide the 'readCookie' and 'saySomeThing' functions from everyone except the newly created object.

I strongly suggest you read up on Douglas Crockford. :-)

Upvotes: 0

user113716
user113716

Reputation: 322472

In javascript, an object has no concept of this.

The value of the this keyword is determined in a function by how that function is called.

For example, in your myObj, if you do:

myObj.readCookie('someName');

Then inside the readCookie function, this will be set to myObj.

If you want site_brand to call the readCookie function, then you should give site_brand its own function that calls it:

site_brand: function() { return this.readCookie('aCookieName'); },

...and call it like:

myObj.site_brand()

...so that this inside the site_brand function is a reference to myObj.


EDIT: The code in the question changed a bit (due to formatting I think).

The answer is the same, but I'd just note that calling this.site_brand in the SaySomeThing function is fine as long as SaySomeThing was called from myObj.

 // this is fine
SaySomeThing: function() {
   alert(this.site_brand);
}

 // as long as you're calling it something like
myObj.SaySomeThing();

Upvotes: 4

ChaosPandion
ChaosPandion

Reputation: 78262

The problem is that this is not what you think it is. It will have the value of the this value in the surrounding scope. Aside from what other users have posted if you wish to take advantage of ECMAScript 5 you can use the new getter syntax.

get site_brand() {
    return this.readCookie('aCookieName');
}

This will allow you to use the property without parentheses.

obj.site_brand // Call the getter.

Upvotes: 0

Phrogz
Phrogz

Reputation: 303207

Per the syntax highlighting above, you appear to have commented out your readCookie method. Is this how your actual code appears?

Upvotes: 0

Jakub Konecki
Jakub Konecki

Reputation: 46008

Try wrapping your site_ properties in functions:

site_brand: function() { return this.readCookie('aCookieName'); }

Upvotes: 0

Related Questions