This question already has an answer here:
I am probably doing something wrong but I found some interesting behavior when trying to apply some object oriented programming to Javascript. Consider the following
function Bug(element) {
this.focusedCell = null;
element.addEventListener('click', this.onClick, true);
};
Bug.prototype.onClick = function(event){
console.log("this is: ");
console.log(this);
};
When I call the method from the console, I see the correct instance of "this" but when I click the element in the document I see the document element in lieu of the instance. So... chances are it's probably not a good idea to use event listeners with instance methods, at least the way I'm doing it.
So the question is:
Is it possible to have an event listener like this that calls an instance method of a javascript object, while preserving the instance in the call?
Is there a better pattern for doing this?
Edit: I haven't tried this in anything but Chrome. But I would imagine that the behavior is the same.
There's a better pattern, and doesn't require much change. I'll show the code first.
By adding the
handleEvent
method, we makeBug
implement theEventListener
interface. This allows us to pass the newBug
object as the second argument toaddEventListener()
instead of a function.Now when the
"click"
event happens, the.handleEvent()
method will be invoked, and the value ofthis
in that method will be theBug
object that was bound.Since
this
is a reference to theBug
instance, it obviously won't be a reference to the element anymore. But it's not necessary, since the element is available viaevent.currentTarget
.Of course, you could add the element directly to your
Bug
object in the constructor if desired.DEMO: http://jsfiddle.net/CnZTa/
This is normal behavior in JavaScript. You can preserve your expected
this
by passing an function the the listener:You can use
Function.prototype.bind
to create a listener bound to whatever this value you want:Older (non-ES5) browsers will need a polyfill such as the one from MDN.