我使用SWFAddress深度链接我的网站(link to SWFAddress)。我喜欢将代码分解为类,因此我有一个类似于此的主结构:
function SomeClass() {
//this adds the this.handleChange() function to the
//SWFAddress event listener
this.initializeSWFA = function() {
//SWFAddress variable is instantiated in SWFAddress javascript file
//so I can use it here
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
}
//SWFAddress suppose to call this function
this.handleChange= function(evt) {
//some code here
}
}
//instantiate the SomeClass
var someVar = new SomeClass();
someVar.initializeSWFA();
这一行在这里不起作用:
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
我尝试将其更改为:
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange());
或
var self = this;
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, self.handleChange);
这些也不起作用。
那么如何在这样的情况下从类中引用javascript函数?如果函数handleChange
在类之外,我可以编写函数的名称。
提前谢谢
修改
首先,谢谢你的所有答案。我仍然试图想象这一切在Javascript中是如何工作的。我不习惯像Javascript这样的面向对象模型。
这是现在的解决方案。我仍然无法弄清楚如何在Javascript中很好地做到这一点,但这个解决方案的工作原理。我试图实现ehudokai建议的解决方案(谢谢),但无法使其正常工作。
function SomeClass() {
//this adds the this.handleChange() function to the
//SWFAddress event listener
this.initializeSWFA = function() {
//SWFAddress variable is instantiated in SWFAddress javascript file
//so I can use it here
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, someFunc);
}
//SWFAddress suppose to call this function
this.handleChange= function(evt) {
//some code here
}
}
//instantiate the SomeClass
var someVar = new SomeClass();
function someFunc(evt) {
someVar.handleChange(evt);
}
someVar.initializeSWFA();
我不喜欢这个,因为这涉及定义一个额外的函数,所以需要额外的空间如果有人想出如何从Javascript对象向SWFAddress EventListener添加方法,请帮助我。
答案 0 :(得分:7)
您的班级结构完全有效。但是,如果您的handleChange()
函数使用this
关键字,期望someVar
,那么这就是您的问题所在。
这就是:
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
正确引用了类中的处理函数。 SWFAddress缓存该函数到某个变量f
,直到调度该事件为止。f
。虽然保留了对函数的引用,但对上下文的引用或this
不是。因此this
默认为window
。要解决这个问题,您只需要使用一个匿名函数来捕获类范围内的变量。您可以使用此匿名函数中的正确上下文调用处理程序:
function SomeClass() {
this.initializeSWFA = function() {
// Save a reference to the object here
var me = this;
// Wrap handler in anonymous function
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, function (evt) {
me.handleChange(evt);
});
}
//SWFAddress suppose to call this function
this.handleChange= function(evt) {
//some code here
}
}
this
:可以用不同的方式解释this
关键字:首先阅读this article about scope,然后阅读this article about object-oriented javascript。
我也想提出我的快速推理,你可能会觉得有帮助。请记住,Javascript没有像Java这样的语言的“类”。在这些语言中,类的“方法”仅属于该类(或可以继承)。然而,在javascript中,只有对象和对象属性才会发生在函数中。这些函数是自由代理 - 它们属于属于一个或另一个对象,就像字符串或数字一样。例如:
var a = {
myMethod: function () {...}
};
var b = {};
b.myMethod = a.myMethod;
在这种情况下,myMethod
属于哪个对象?没有答案,可以是a
或b
。因此a.myMethod
只是对函数的引用,与“上下文”或父对象不相关。因此this
没有任何意义,除非使用a.myMethod()
或b.myMethod()
明确调用,因此在以任何其他方式调用时默认为window
。出于同样的原因,javascript中没有parent
或super
关键字。
答案 1 :(得分:1)
我担心我无法确定您的问题,但我会说这与您使用SWFAddress
有关。您构建SomeClass
的方式及其方法是完全有效的,与此处的其他答案相反。
进一步澄清miki(现已删除)的问题来自另一个答案,关于this
如何运作:
this
的行为方式有两种情况;使用new
- 运算符调用的常规函数和函数。
对于常规函数调用,this
引用点左侧的对象(松散地说):例如,在编写someVar.initializeSWFA()
时,this
将引用{{1} }}。调用不带点的函数时,someVar
将引用全局对象。可以将一个函数从一个对象分配给另一个对象,因此this
将被移位,如下所示:
this
然后,当使用var someVar = new SomeClass();
var anotherVar = {};
anotherVar.aNewNameForTheSameFunction = someVar.initializeSWFA;
anotherVar.aNewNameForTheSameFunction(); // inside of this call to initializeSWFA, "this" will be "anotherVar"
- 运算符调用时,我们也会遇到这种情况。在这种情况下,new
将为您创建一个新对象,new
将引用该对象。
通过使用this
- 函数,还有一些方法可以使用显式设置this
来调用函数:
call
这将调用函数initializeSWFA var someVar = new SomeClass();
var aNumber = 5;
someVar.initializeSWFA.call(aNumber, arg1, arg2, ..., argN);
作为aNumber
,并将参数this
,arg1
等传递给它。请注意arg2
已被采用在那种情况下不合时宜。
答案 2 :(得分:1)
我认为最好的办法是停止将SomeClass视为一个类。
Javascript没有课程。它使用原型继承。我不会在这里深入探讨。基本上它意味着你只有对象。如果你想创建另一个像第一个对象,你可以使用Object.prototype属性来做到这一点。
所以,如果你想做你想做的事情。 (假设SWFAddress与大多数javascript一样),请执行以下操作。
var someVar = { // (using object notation)
initializeSWFA : function(){
SWFAddress.addEventListener(SWFAddressEvent.CHANG, this.handleChange);
},
handleChange : function(){
// your code here
}
}
此时你可以直接调用someVar
someVar.initializeSWFA();
如果您想要创建一个可以继承其他对象的对象,请尝试以下操作。
var baseObject = function(){};
baseObject.prototype.handleChange = function(){
// your code here
}
baseObject.prototype.initializeSWFA = function(){
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
}
var someVar = new baseObject();
someVar.initializeSWFA();
new运算符只是创建一个新对象,该对象继承了指定对象的.prototype。
希望有所帮助。