OO Javascript和这个关键字.对象文字

OO Javascript and this keyword. Object Literals

本文关键字:关键字 对象 文字 Javascript OO      更新时间:2023-09-26

我有Javascript属性和"this"关键字的问题。请原谅我在这里问我的第三个也是最后一个JS OOP问题。Javascript中的OOP一直让我很头疼。

我试图设置属性'source',但错误控制台说它在parseSource方法中未定义。

经过一些研究,我相信这一点。Source is指的是window。Source ?该代码是来自Mozilla的样板文件。创建扩展时,init会在插件初始化时被FireFox调用。

在使用文字符号创建对象时,设置属性的最佳方法是什么?

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

当您向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();
},

编辑

一个简化的演示:http://jsfiddle.net/mattball/bDe6N/

问题是,如果您将其作为参数传递,javascript中的方法会忘记它们的this。它们只有在像方法一样传递时才有效

//this doesn't work in JS
f = obj.method
f()
//wtf man! You have to call it looking like a method
obj.method()

在你的例子中,这是因为你传递了这个。onPageLoad作为参数。函数参数的作用类似于上一个例子中的变量。

解决方法是使用包装器函数来保持方法调用的外观

addEventListener( ..., function(){ return this.onPageLoad(); }, ...)

除了this没有词法作用域,而且内部函数也得到了一个错误的副本。在另一个快速修复之后,我们得到

var that = this;
addEventListener(..., function(){ that.onPageLoad(); }, ...);

现在应该可以了