Reputation: 2337
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
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
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
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