我正在为Firefox(3.6。*)开发一个附加组件。在以下代码中notify
从init
内部调用的工作正常,但在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);
答案 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
将引用的内容。除非你真的想要标准行为;在这种情况下,您可能希望查看call
和apply
方法。此链接可能有所帮助:Function.apply and Function.call in JavaScript
您可能还想查看最近添加的JavaScript(可在FireFox 4中使用):bind
方法:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
另一个直接解决您问题的链接:https://developer.mozilla.org/en/DOM/element.addEventListener#The_value_of_this_within_the_handler
答案 2 :(得分:0)
添加事件侦听器而不丢失this
的另一种方法是将this
本身作为事件侦听器传递。但是,您的功能总是被称为handleEvent
,因此如果您有许多侦听器(除非它们都针对不同的事件,在这种情况下您可以打开事件的类型),它就不那么有用了。