我遇到了Javascript属性和“this”关键字问题。请原谅我在这里询问我的第三个也是最后一个JS OOP问题。 Javascript中的OOP今天让我头疼。
我正在尝试设置属性'source',但错误控制台说它在parseSource方法中未定义。
经过一番研究后,我相信this.source是指window.source?代码是Mozilla的样板。创建扩展时,初始化插件时,FireFox会调用init。
使用文字符号创建对象时,设置属性的最佳方法是什么?
var myExtension = {
source: null,
init: function() {
// The event can be DOMContentLoaded, pageshow, pagehide, load or unload.
if(gBrowser) {
gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
}
},
onPageLoad: function(aEvent) {
doc = aEvent.originalTarget; // doc is document that triggered the event
win = doc.defaultView; // win is the window for the doc
// Skip frames and iFrames
if (win.frameElement) return;
this.source = win.document.getElementById('facebook').innerHTML;
myExtension.parseSource();
},
parseSource: function() {
if(this.source == null) {
// So something
} else {
// Do something else
}
}
}
window.addEventListener("load", function() { myExtension.init(); }, false);
答案 0 :(得分:1)
当您将回调函数传递给gBrowser.addEventListener
时,如下所示:
gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
您正在传递对该函数的引用,该函数基本上是"已分离的"来自定义它的this
对象。因此,您需要执行以下操作才能正确维护this
引用:
init: function() {
var self = this;
if(gBrowser) {
gBrowser.addEventListener("DOMContentLoaded", function () {
self.onPageLoad();
}, false);
}
},
在较新的浏览器中(您确实说这是FF扩展名),您可以使用Function.bind
来达到同样的效果:
init: function() {
if(gBrowser) {
gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad.bind(this), false);
}
},
清除完毕后,您可以将onPageLoad
功能更改为:
onPageLoad: function(aEvent) {
doc = aEvent.originalTarget; // doc is document that triggered the event
win = doc.defaultView; // win is the window for the doc
// Skip frames and iFrames
if (win.frameElement) return;
this.source = win.document.getElementById('facebook').innerHTML;
this.parseSource();
},
答案 1 :(得分:0)
问题是Javacript中的方法如果将它们作为参数传递,就会忘记它们this
。它们只有在你看起来像一个方法传递它们时才能工作
//this doesn't work in JS
f = obj.method
f()
//wtf man! You have to call it looking like a method
obj.method()
在您的情况下,这是因为您将this.onPageLoad作为参数传递。函数参数的作用类似于上一个示例中的变量。
解决方法是使用包装函数来保留方法调用外观
addEventListener( ..., function(){ return this.onPageLoad(); }, ...)
除了this
不是lexicaly作用域,内部函数也得到错误的副本。经过另一次快速解决后,我们获得了
var that = this;
addEventListener(..., function(){ that.onPageLoad(); }, ...);
这应该可以胜任。