Firefox附加组件 - “this”在一个方法中起作用,但在同一个对象的另一个方法中失败

时间:2010-12-06 12:06:55

标签: javascript firefox-addon this

我正在为Firefox(3.6。*)开发一个附加组件。在以下代码中notifyinit内部调用的工作正常,但在this.notify is not a function内调用时,我收到错误onPageLoad。那是为什么?

此外,当我将呼叫更改为myextobj.notify('title', 'msg')时,它仍然有效。访问变量也是如此。那么,this和对象名称作为前缀有什么区别?

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);

3 个答案:

答案 0 :(得分:2)

执行此操作时:

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

您只需将onPageLoad中保存的函数添加为事件处理程序。与对象的连接丢失,this将在执行时引用全局对象。

只需像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);

请记住,函数是JavaScript中的第一类对象,它们可以像任何其他值一样传递。函数没有引用它们所定义的对象,因为它们不属于该对象。它们只是另一种数据。

函数中的this引用的对象是在执行时决定的,取决于执行函数的 context 。如果你调用obj.func()那么上下文是obj,但是如果你将函数分配给另一个变量,就像var a = obj.func之前那样(那就是你用添加事件处理程序(在某种程度上)),然后调用a(),{{ 1}}将引用全局对象(大部分时间都是this)。

答案 1 :(得分:2)

为活动调用onPageLoad时,“此”不会指代您的myextobj。因为它没有在对象myextobj的上下文中调用。

我处理这个问题的方法是,通过使用以下约定来拥有对象的所有成员函数。

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

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

了解如何将myObj设为t,以节省打字并明确使用this的意图。

现在,您可以从任何上下文安全地调用您的方法,而不必担心this将引用的内容。除非你真的想要标准行为;在这种情况下,您可能希望查看callapply方法。此链接可能有所帮助:Function.apply and Function.call in JavaScript

答案 2 :(得分:0)

添加事件侦听器而不丢失this的另一种方法是将this本身作为事件侦听器传递。但是,您的功能总是被称为handleEvent,因此如果您有许多侦听器(除非它们都针对不同的事件,在这种情况下您可以打开事件的类型),它就不那么有用了。