Alessandro Alessandro - 2 months ago 17
Javascript Question

Object oriented Javascript: event handling

I'm trying to create an event for an object to have it listen to it. Consider the following example:

var moon;

moon = document.createEvent("Event");
moon.initEvent("Event",true,true);

var Dog = function (name) {
this.name = name;

document.addEventListener("Event",this.bark,false);
};
dog.prototype.bark = function() {
console.log(this.name + ': Awooooooof Woof!');
};


var spot = new Dog("Spot");
var dot = new Dog("Dot");


//invoke
document.dispatchEvent(moon);


I'm expecting to receive an output like:

Spot: Awooooooof Woof!

Dot: Awooooooof Woof!


But what I get is:

undefined: Awooooooof Woof!


What is wrong with my example? How can I register a listener that every instance of Dog has?
Thanks in advance!

Answer

In this line

document.addEventListener("Event",this.bark,false);

you don't bind the scope of this.bark to this. In JavaScript, the value of this does not depend on where the function is defined but from where it is called. This means when you pass this.bark to addEventListener you detach it from the current object.

In frameworks like prototype.js and JQuery there are shortcuts for binding this, with vanilla JavaScript you can do it like this:

function bind(scope, fn) {
   return function() {
      return fn.apply(scope, arguments);
   }
}

And then:

document.addEventListener("Event",bind(this, this.bark),false);