(on a extrait quelques explications qui étaient cachées dans les commentaires de l'autre réponse)
Le problème réside dans la ligne suivante :
this.dom.addEventListener("click", self.onclick, false);
Ici, vous passez un objet fonction qui sera utilisé comme callback. Lorsque l'événement se déclenche, la fonction est appelée, mais elle n'est plus associée à aucun objet (this).
Le problème peut être résolu en enveloppant la fonction (avec sa référence objet) dans une fermeture comme suit :
this.dom.addEventListener(
"click",
function(event) {self.onclick(event)},
false);
Puisque la variable self a été assignée ce lorsque la fermeture a été créée, la fonction de fermeture se souviendra de la valeur de la variable self lorsqu'elle sera appelée ultérieurement.
Une autre façon de résoudre ce problème est de créer une fonction d'utilité (et d'éviter d'utiliser des variables pour la liaison ce ):
function bind(scope, fn) {
return function () {
fn.apply(scope, arguments);
};
}
Le code mis à jour serait alors le suivant :
this.dom.addEventListener("click", bind(this, this.onclick), false);
Function.prototype.bind
fait partie de l'ECMAScript 5 et offre la même fonctionnalité. Vous pouvez donc le faire :
this.dom.addEventListener("click", this.onclick.bind(this), false);
Pour les navigateurs qui ne supportent pas encore ES5, MDN fournit la cale suivante :
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}