Javascript addEventListener及其范围
我有一个第三方flash对象,我可以通过他们提供的javascript API对其进行操作。我试着听这个物体上的一个事件,然后在我的物体内激发事件,进一步激发事件。我碰巧正在使用ExtJS,但我认为它在这里并不重要 示例代码Javascript addEventListener及其范围,javascript,this,Javascript,This,我有一个第三方flash对象,我可以通过他们提供的javascript API对其进行操作。我试着听这个物体上的一个事件,然后在我的物体内激发事件,进一步激发事件。我碰巧正在使用ExtJS,但我认为它在这里并不重要 示例代码 this.chart.addEventListener('create', function() { this.fireEvent('created'); }, false) 我的问题是,匿名函数中的“this”指的是触发事件的对象,而不是我想要触发事件的对象 这
this.chart.addEventListener('create', function() {
this.fireEvent('created');
}, false)
我的问题是,匿名函数中的“this”指的是触发事件的对象,而不是我想要触发事件的对象
这是另一个范围问题。提前感谢您的帮助。在引用“this”对象之前创建一个外部变量怎么样。 例如:
var _this = this;
this.chart.addEventListener('create', function() { _this.fireEvent('created'); }, false)
这是解决此问题的典型方法:-
(function(self) {
self.chart.addEventListener('create', function() {self.fireEvent('created');}, false);
})(this);
虽然其他答案可以满足您的需要,但它们并不能以最高效(可伸缩)的方式工作,因为它们最终不会将视图对象(
this.chart
)与该视图的逻辑(firevent()
)解耦。在MVC应用程序中,这些视图“决策”驻留在控制器中。控制器“控制”视图,并应包含视图可能访问的所有API
在您的示例中,这个
就是控制器,这很好(这意味着您在正确的位置添加了侦听器)。您真正需要做的就是将处理程序绑定到应该进行“处理”的对象的范围——在您的情况下:this
:
// `this` is the controller of `chart`
this.chart.addEventListener('create', function() {
this.fireEvent('created');
}.bind(this));
本页上的其他答案所做的是,通过使用var self=this
为“控制器”分配临时引用,使视图成为自己的控制器,但仅在处理“创建”事件时。同样,这很好,但在事件驱动的应用程序中,它不能很好地按比例工作,而且如果有很多事件要处理,它也没有真正的意义
.bind()
是一个ECMAScript 5实现。如果需要在更旧的浏览器中工作,这里介绍了一种很好的方法(使用函数和调用()
):是的,这是正常的习惯用法。闭包变量通常被称为,即或self
(尽管我认为后者不是一个好主意,因为self
有一个 — 虽然没用 — 在JavaScript中存在的含义)。好的,那就行了。出于兴趣,除了设置变量之外,还有其他方法。例如使用闭包?@bobince:我更喜欢self
<代码>自身
通过窗口
自身引用公开。我很乐意在其他范围内重用该标识符。在我看来,它的意思是正确的,与它的意思并不冲突,它的意思是当self
恰好是窗口时代码>。创建一个函数,然后在传递此
的同时执行它,因为参数似乎有点过火-代码也稍长;-)@安迪:是的,当代码存在于一个小的执行上下文中时,我也经常这样做。然而,以上是标准方法,适用于更广泛的场景。self
标识符的范围仅限于闭包,在事件触发之前,后续代码不会修改其中包含的值。对于var self=This,情况并非如此代码>方法。在一些MVC实现中(如这里描述的示例中),处理程序本身(例如,您的.firevent()
)在视图中定义,但控制器会根据需要调用它。这可能允许您根本不使用.bind()
或自引用,但会使您的处理程序非常不可调;您的应用程序将变得非常庞大。