2010-12-06 20 views
2

Je développe un module pour Firefox (3.6. *). dans le code suivant notify appelé de l'intérieur init fonctionne très bien, mais j'obtiens une erreur en disant this.notify is not a function quand il est appelé à partir de onPageLoad. Pourquoi donc?Add-on Firefox - `this` fonctionne dans une méthode mais échoue dans une autre méthode du même objet

Aussi quand je change l'appel à myextobj.notify('title', 'msg'), cela fonctionne. La même chose est vraie pour l'accès aux variables. Alors, quelle est la différence entre this et le nom de l'objet en tant que préfixe?

var myextobj = { 
    init: function() { 
    this.notify('init', 'We are inside init'); 
    ... 
    var appcontent = document.getElementById("appcontent"); // browser 
    if(appcontent) 
     appcontent.addEventListener("DOMContentLoaded", this.onPageLoad, true); 
    }, 
    onPageLoad: function(aEvent) { 
    this.notify('onPageLoad', 'We are inside onPageLoad'); 
    ... 
    }, 

    notify: function (title, text) { 
    Components.classes['@mozilla.org/alerts-service;1']. 
     getService(Components.interfaces.nsIAlertsService). 
     showAlertNotification(null, title, text, false, '', null); 
    } 
}; 
window.addEventListener("load", function() { myextobj.init(); }, false); 

Répondre

2

Lorsque vous faites ceci:

appcontent.addEventListener("DOMContentLoaded", this.onPageLoad, true); 

vous suffit d'ajouter la fonction qui est de tenir dans onPageLoad comme gestionnaire d'événements. La connexion à l'objet est perdue et this fera référence à l'objet global lorsqu'il est exécuté.

il suffit de créer une fonction anonyme comme vous le faites pour l'événement load:

var that = this; // capture reference to object 
appcontent.addEventListener("DOMContentLoaded", function(event) { 
    that.onPageLoad(event); 
    // myextobj.onPageLoad(event); should also work in this case 
}, true); 

Rappelez-vous que les fonctions sont des objets de première classe en JavaScript, ils peuvent être passés autour comme toute autre valeur. Les fonctions n'ont aucune référence à un objet sur lequel elles sont définies, car elles n'appartiennent pas à cet objet. Ils sont juste un autre type de données.

à quel objet this fait référence à une fonction est décidée lors de l'exécution et dépend du contexte la fonction est exécutée. Si vous appelez obj.func() alors le contexte est obj, mais si vous attribuez la fonction à une autre variable avant comme var a = obj.func (c'est-wat que vous faites avec l'ajout du gestionnaire d'événements (de manière)), puis appelez a(), this se référera à l'objet global (qui est window la plupart du temps).

2

Lorsque onPageLoad est appelé pour l'événement, 'ceci' ne fait pas référence à votre myextobj. Parce qu'il n'a pas été appelé dans le contexte de votre objet myextobj.

La façon dont je traite cela est, en ayant toutes les fonctions membres d'un objet en utilisant la convention suivante.

var myObj = { 
    ..... 
    counter: 0, 
    ..... 
    myFunction: function() { 
    var t = myObj; 
    t.myOtherFunc(); 
    }, 

    .... 
    myOtherFunc: function() { 
    var t = myObj; 
    t.counter++; 
    } 
}; 

Voyez comment, j'aliasing myObj comme t, pour sauver le frappe et faire mon intention d'utiliser this clair.

Maintenant, vous pouvez appeler vos méthodes en toute sécurité de tout contexte sans se soucier de ce que this serait allusion. Sauf si vous voulez vraiment le comportement standard; Dans ce cas, vous pouvez regarder les méthodes call et apply.Ce lien pourrait aider: Function.apply and Function.call in JavaScript

0

L'autre façon d'ajouter un écouteur d'événement sans perdre de vue this est de passer lui-même comme this l'écouteur d'événement. Cependant vous êtes limité en ce que la fonction est toujours appelée handleEvent, donc c'est moins utile si vous avez beaucoup d'écouteurs (à moins qu'ils ne soient tous pour des événements différents, auquel cas vous pouvez activer le type de l'événement).