我是OOP Javascript的新手,我遇到了this
关键字和事件的问题。
我想要实现的是:我有多个DOM对象,并且不仅要将公共事件绑定到它们,还要在全局容器中保留有关上述对象的一些数据(以提高运行时性能)。
所以我所做的基本上是这样的:
function ClassThatDoesSomething() {
/* keeps node ids for processing in this.init */
this.nodes = new Array();
/* keeps processed node data for fast access */
this.nodeData = new Array();
this.sthAddNodes = function(/* ids */) {
/* appends node ids to local variable (this.nodeData) */
}
function init() {
/* gathers data from all nodes that were
added before and stores it in this.nodeData */
/* here, unsurprisingly, 'this' references the window element*/
addEvent(window,'scroll',this.scroll);
}
function scroll() {
/* do stuff when user scrolls the page */
/* 'this' references the window element here too */
}
addEvent(window,'load',this.init);
}
稍后,在文档正文中,我可以添加:
var Ctds = new ClassThatDoesSomething();
然后,通过以下方式添加DOM元素:
Ctds.addNodes(ids);
不需要进一步的实施代码。
问题: 如何在init
和scroll
方法中访问 JS类实例并 窗口元素。
我知道,它不一定要通过this
关键字,但我仍然没有想出任何东西。
P.S。
addEvent
是附加事件的一个非常基本的功能,它只是IE / Fx友好而且什么都不做。答案 0 :(得分:10)
我注意到的一点是,init
和scroll
都不是实例上的方法。
因此,您只需要在加载事件中添加init
而不是this.init
:
addEvent(window,'load',init); // No "this." needed
同样地:
addEvent(window,'scroll',scroll);
如果你决定将它们移到课堂上(例如this.scroll
和this.init
等),你可以保存对this
的引用并在传递给它的匿名函数中引用它addEvent
:
var self = this;
this.init = function() {
addEvent(window, 'scroll', function() {
self.scroll()
})
};
this.scroll = function() { /* ... */ };
addEvent(window,'load',function() {
self.init()
});
这称为closure。
答案 1 :(得分:2)
function MyConstructor() {
this.foo = "bar";
var me = this;
function myClosure() {
doSomethingWith(me.foo);
}
}
答案 2 :(得分:1)
this
。在附加事件侦听器时,您传递的是函数,它不带有范围。因此,在指定的事件上,该函数在window
的范围内运行,这意味着this
将等于window
。要强制执行特定范围,您可以使用诸如创建新变量等等this
之类的技巧,例如:
var that = this;
...
addEvent(window,'scroll', function() {
that.scroll()
});
答案 3 :(得分:1)
向Function原型添加一个方法,允许您将任何函数绑定到任何对象:
Function.prototype.bind = function(object) {
var __method = this;
return function() {
return __method.apply(object, arguments);
};
};
在实例中声明您的事件处理程序(保持整洁):
function ClassThatDoesSomething() {
this.events = {
init: ClassThatDoesSomething.init.bind(this),
scroll: ClassThatDoesSomething.scroll.bind(this),
etc: ClassThatDoesSomething.etc.bind(this)
};
...
}
现在无论何时引用事件,它们都会自动绑定到类实例。 e.g:
function init() {
addEvent(window,'scroll',ClassThatDoesSomething.events.scroll);
}
答案 4 :(得分:0)
您可以使用闭包:
function ClassThatDoesSomething() {
var self=this;
// ...
function init() {
addEvent(window,'scroll',self.scroll);
}
}
答案 5 :(得分:0)
这样做:
var ClassThatDoesSomething = function() {
/* keeps node ids for processing in this.init */
this.nodes = new Array();
/* keeps processed node data for fast access */
this.nodeData = new Array();
}
ClassThatDoesSomething.prototype.sthAddNodes = function(/* ids */) {
/* appends node ids to local variable (this.nodeData) */
}
}
ClassThatDoesSomething.prototype.init = function() {
/* gathers data from all nodes that were
added before and stores it in this.nodeData */
/* here, unsurprisingly, 'this' references the window element*/
addEvent(window,'scroll',this.scroll);
}
}
ClassThatDoesSomething.prototype.scroll = function() {
/* do stuff when user scrolls the page */
/* 'this' references the window element here too */
}
addEvent(window,'load',this.init);
}
答案 6 :(得分:-1)
这个技巧应该有效:
function ClassThatDoesSomething() {
...
this.This = this;
...
}
然后在这些有问题的方法中,您可以使用'This'
。
希望这有帮助。