[thelist] 'classes' in javascript

Keith Gaughan keith at digital-crew.com
Wed Jun 15 06:24:48 CDT 2005


Matt Warden wrote:

> function RemoteConnection()
> {
>     this.aRequests = new Array();
>     this.aRequests[0] = null;
>     
>     this.request = function(url, method, requestxml)
>         {
>         alert(this);
> // ...
>         };
>     
>     
>     this.handle = function()
>         {
>             alert(this);
> // ...
>         }; // end method handle
> 
> // ...    
> 
> } // end class RemoteConnection

Two tips for the price of one!

<tip title="Modules and Singleton objects in JavaScript">
To supplement what Volkan wrote, what you're actually trying to simulate
here is more like a module or singleton object. As far as this goes,
you'll have better luck if you write such objects as follows:

    var RemoteConnection =
    {
        // "Private" variables.
        _requests: [],

        // Initialiser: called after the object is constructed.
        _initialise: function()
        {
            this._requests[0] = null;
        },

        request: function(url, method, requestXML)
        {
            // ...
        },

        handle: function()
        {
            // ...
        }

        // And so on.
    };

    RemoteConnection._initialise();

Prefix all references to methods and instance variables within the
object with "this".
</tip>

> The first time I RemoteConnection().request(...) is called first, and
> the alert reports that 'this' is an object. This is what I expect. The
> second method fired is .handle(); this is actually being fired by an
> event trigger that is set up in request():
>
> req.onreadystatechange = this.handle;
>
> The second alert (in handle()) alerts the contents of the function
> (i.e., literally the function's code). I seemingly do not have access
> to the properties of teh containing 'class' (RemoteConnection).
>
> I want to be able to refer to the current RemoteConnection instance.
> How can I do this?
>
> Thanks,

<tip title="'this' and closures in JavaScript">
Now onto the topic of ensuring that the correct method is called for
your object handlers.

"this" in JavaScript always refers to the parent object. It's behaviour
is consistent but slightly counterintuitive in places.

Say you've the following module/singleton

    var singleton =
    {
        _pvtVar: 42,

        initialise: function(obj)
        {
            obj.onfoo = this.callback;
        },

        callback: function()
        {
            alert(this._pvtVar);
        }
    };

When the "foo" event fires on the object you passed into
singleton.initialise(), "this" in callback() will refer to
that object rather than "singleton". That's because at the moment
of its execution, the parent object of the callback() closure was
the object passed into initialise() rather than "singleton".

To get around this, rewrite initialise as follows:

    var singleton =
    {
        // ...

        initialise: function(obj)
        {
            var self = this;
            obj.onfoo = function()
            {
                self.callback();
            };
        },

        // ...
    };

This way, the "self" variable will contain a reference to "singleton"
and dispatch the call to the closure on the correct object.
</tip>

K.


More information about the thelist mailing list