Moshe Marciano
Moshe Marciano

Reputation: 2337

Javascript class instance problem

I am trying to figure out JavaScript OOP, I tried the following which works but fails when I need to make a change to a class variable on a specific instance.

I have "myname" with a default value, I then change it for a specific instance and in an event handler I print it's value. I get the default value and not the updated one.

how can I change the code to support this ?

thanks

function myClass () {}

myClass.prototype = 
{

    myname : "test",

    test  : function (filename)
    {
        var img = createSomething ();
        img.container = this;

        img.addEventListener('click', this.onClick);                    
    }, 


    onClick : function (e)
    {
        trace ("click: " + e.source.container.myname); // this will print "test" and not "dave"
    }

};



var instance = new myClass ();

instance.myname = "dave";

instance.test();

Upvotes: 0

Views: 1514

Answers (3)

Chetan S
Chetan S

Reputation: 23803

If you really want to do OOP, you must use a bind function. It is extremely useful when you want to attach event handlers that are bound to your object rather than the global object.

function bind(func, context) {
     return function() {
          return func.apply(context, Array.prototype.slice.call(arguments));
     }
}

Then you do this-

function MyClass() {}

MyClass.prototype = {

    myname: "test",

    test: function(filename) {
        var img = new Image();
        img.src = "http://dummyimage.com/120x90/f00/fff.png&text=my+image"

        img.addEventListener('click', bind(this.onClick, this), false);
        document.body.appendChild(img);
    },
    onClick: function(e) {
        //this here refers to the instance of MyClass
        console.log("click: " + this.myname); 
    }
};
var instance = new MyClass();
instance.myname = "dave";
instance.test();

PS: As a convention, constructor functions (or 'Classes') begin with an uppercase letter.

Upvotes: 0

Jakub Konecki
Jakub Konecki

Reputation: 46008

Note: not a direct answer to the question.

For OOP in Javascript I would strongly recommend using following Class class by John Resig himself: http://ejohn.org/blog/simple-javascript-inheritance/

It makes inheritance so much nicer...

Upvotes: 0

user113716
user113716

Reputation: 322492

I don't know what trace() and e.source are, but when I take your example, and use console.log() and e.target.container.myname, it works perfectly.

Example: http://jsfiddle.net/L2UMC/2/

(note that the example is only intended to work in browsers that support addEventListener)

function myClass() {}

myClass.prototype = {

    myname: "test",

    test: function(filename) {
        var img = new Image();
        img.src = "http://dummyimage.com/120x90/f00/fff.png&text=my+image"
        img.container = this;

        img.addEventListener('click', this.onClick, false);
        document.body.appendChild(img);
    },
    onClick: function(e) {
        console.log("click: " + e.target.container.myname); 
    }
};
var instance = new myClass();
instance.myname = "dave";
instance.test();

EDIT: Made the addEventListener more compatible by adding the 3rd argument, as correctly suggested by @Felix Kling.

Upvotes: 2

Related Questions