我正在尝试封装一些代码以获取和释放Firefox扩展中的选项卡的onLoad事件,以便在必要时调用:
var onLoad = new MyHandler_onLoad();
然后当我完成时,我打电话给:
onLoad.unregister();
原则上,此代码实现上述罚款,直到您深入研究砂砾细节。
function bind(scope, fn) {
return function(){
fn.apply(scope, arguments);
};
function MyHandler_onLoad()
{
this.scan = function() {
do_scan(this.browser); // this.browser == undefined
};
this.register = function() {
this.tab.addEventListener("load", this.scan, false);
};
this.unregister = function() {
this.tab.removeEventListener("load", this.scan, false);
};
this.tab = gBrowser.selectedTab;
this.browser = gBrowser.selectedBrowser;
this.register();
window.addEventListener("unload", bind(this, this.unregister), false);
};
由于JavaScript this
的行为,我正在努力。我希望能够从我的扫描功能访问this.browser,但不能。
我已使用bind
确保unregister
获得unload
上的相应上下文。但是,我无法通过调用scan
来执行此操作,因为如果我没有名字,我将无法将其删除。
在JavaScript中执行此类操作是否有良好的模式?
我已经尝试将bind(this,this.scan)的结果存储为构造函数中的变量,但它没有帮助,现在我正在努力争取选项。
答案 0 :(得分:3)
this
,在JavaScript中,始终指向当前对象。如果没有当前对象,this
指向window
,总是顶级范围(无论如何都在浏览器中)
以示例:
function(){
...
this.foo = function(){
this;
// There is no object here, so `this` points to `window`
}
}
function foo(){
this;
// again, no object so `this` points to window`
}
foo();
function foo(){
this;
// because initialized with `new`, `this` points to an instance of `foo`
this.bar = function(){
this;
// no object, `this` points to `window`
}
}
var foobar = new foo();
// above is roughly equivalent to: foo.apply({}, arguments); Note the new object
foobar.bar();
var foo = {
bar : function(){
this;
// `this` points at `foo` -- note the object literal
}
};
function foo(){
}
foo.prototype.bar = function(){
this;
// `this` points to the instance of `foo`
}
var foobar = new foo();
foobar.bar();
绑定的概念允许您将this
变量锁定到您想要的任何内容,因为最后一次调用该函数是通过.apply(scope, params)
,所以回到原来的问题,我上面的上一个例子将起作用,所以这个:
function foo(){
this.scan = bind(this, function(){
this;
// `this` points to instance of `foo` IF `foo` is instantiated
// with `new` keyword.
});
}
new foo()
如果你想更好地理解这一切,我有两篇文章我写回来应该有所帮助:
http://www.htmlgoodies.com/primers/jsp/article.php/3600451/Javascript-Basics-Part-8.htm http://www.htmlgoodies.com/primers/jsp/article.php/3606701/Javascript-Basics-Part-9.htm
答案 1 :(得分:1)
function MyHandler_onLoad()
{
var self = this;
完成此操作后,self
将始终指向处理程序中的正确对象。
答案 2 :(得分:0)
解决方案:请勿使用this
。
以下是定义MyHandler_onLoad
function MyHandler_onLoad() {
var onload_handler = {
scan: function() {
do_scan(onload_handler.browser); // onload_handler.browser == undefined
},
register = function() {
onload_handler.tab.addEventListener("load", onload_handler.scan, false);
},
unregister = function() {
onload_handler.tab.removeEventListener("load", onload_handler.scan, false);
}
};
onload_handler.tab = gBrowser.selectedTab;
onload_handler.browser = gBrowser.selectedBrowser;
onload_handler.register();
window.addEventListener("unload", bind(onload_handler, onload_handler.unregister), false);
return onload_handler;
}
更好?移动全局依赖项,无法访问选项卡和浏览器属性(即将它们设置为“私有”)
你甚至可以选择隐藏注册和取消注册功能,因为我不确定你是否需要它们,因为它似乎已经附加了。
var handler = MyHandler_onLoad(gBrowser.selectedTab, gBrowser.selectedBrowser);
function MyHandler_onLoad(tab, browser) {
var onload_handler = {
scan: function() {
do_scan(browser); // browser == undefined
},
register = function() {
tab.addEventListener("load", onload_handler.scan, false);
},
unregister = function() {
tab.removeEventListener("load", onload_handler.scan, false);
}
};
onload_handler.register();
window.addEventListener("unload", bind(onload_handler, onload_handler.unregister), false);
return onload_handler;
}
具体来说,this
的问题在于它指向扫描功能,而不是处理程序对象。如果您根本不使用this
,那么您将永远不会遇到这些类型的错误。
哦,您也不需要使用new
。