考虑以下Javascript类:
function ClassA() {
this.someVariable = someValue;
this.myHandler = function(){
// I WANT TO CALL InnerFunction
this.innerFunction();
};
this.innerFunction = function(){
// do something that accesses/manipulates someVariable
};
this.hookUp = function(id){
document.getElementById(id).onclick = this.myHandler;
};
};
...
...
var button = document.createElement('button');
button.setAttribute('id','mybuttonid');
// append button to the document
...
...
var x = new ClassA();
x.hookUp('mybuttonid');
当我单击按钮时,处理程序执行,但是,'this'现在引用了button元素而不是ClassA对象,所以它无法解析innerFunction()。
我需要的是一种向处理程序指示此上下文是ClassA实例的方法(类似于$ .ajax({context:this ....}),您可以使用'this'在.done()或.error()处理程序中),或者是将实例的引用传递给处理程序而不使处理程序在实例化时执行的方法。例如,如果我尝试将'this'作为praremter传递给myHandler(myHandler = function(ref){},然后更改:document.getElementById(id).onclick = this.myHandler(this);) 但是当您向myHandler添加参数时,该函数将在类实例化时执行,而不是在单击时执行。
非常感谢任何帮助。
答案 0 :(得分:2)
替换...
this.myHandler = function(){
this.innerFunction();
};
...与......
var self = this;
this.myHandler = function() {
self.innerFunction();
};
按照惯例,我们制作一个私人
that
变量。这是用来制作的 私有方法可用的对象。这是一个解决方法 ECMAScript语言规范中的错误导致this
内部功能设置不正确。
答案 1 :(得分:1)
就像您已经发现的那样,this
的值取决于方法的调用方式。因此,在附加到DOM元素的事件处理程序中使用this
时可能会造成混淆。
相反,在添加处理程序时,请使用匿名方法以及闭包中的变量。
例如,将您的连接功能更改为:
this.hookUp = function(id) {
var _this = this;
document.getElementById(id).onclick = function() {
_this.innerFunction();
}
}
请注意,您不再依赖于onclick处理程序中的thi
,从而避免了问题。进入innerFunction
后,您可以像往常一样继续使用this
,因为它现在可以正确指向正确的对象。
有关this
在函数中如何工作的更深入解释,MDN有一个很好的article about the this
keyword.
答案 2 :(得分:0)
通常使用所谓的“代理模式”来解决这个问题。
我认为这会有所帮助( - !
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#proxypatternjquery