Javascriptclosures和'这个'
我创build的对象有一个问题,如下所示:
var myObject = { AddChildRowEvents: function(row, p2) { if(document.attachEvent) { row.attachEvent('onclick', function(){this.DoSomething();}); } else { row.addEventListener('click', function(){this.DoSomething();}, false); } }, DoSomething: function() { this.SomethingElse(); //<-- Error here, object 'this' does not support this method. } }
问题是,当我在“DoSomething”函数内部时,“this”没有引用“myObject”,我做错了什么?
当函数被调用时,“this”是指行。 如果你想拥有这个对象,你可以这样做:]
AddChildRowEvents: function(row, p2) { var theObj = this; if(document.attachEvent) { row.attachEvent('onclick', function(){theObj.DoSomething();}); } else { row.addEventListener('click', function(){theObj.DoSomething();}, false); } },
当函数被调用时,它可以访问定义函数时在范围内的variablestheOBj。
this
总是指内部函数,如果你有嵌套的函数,你必须创build另一个variables,并指出这this
。
var myObject = { AddChildRowEvents: function(row, p2) { var that = this; if(document.attachEvent) { row.attachEvent('onclick', function(){that.DoSomething();}); } else { row.addEventListener('click', function(){that.DoSomething();}, false); } } }
这是closures的常见问题。 要解决它,尝试这样的事情:
var myObject = { AddChildRowEvents: function(row, p2) { var self = this; if(document.attachEvent) { row.attachEvent('onclick', function(){this.DoSomething(self);}); } else { row.addEventListener('click', function(){this.DoSomething(self);}, false); } }, DoSomething: function(self) { self.SomethingElse(); } }
你的代码的问题在这里,在下面的代码行中,你已经定义了一个匿名函数,并将它作为onClick事件的事件处理函数传递,如下所示:
row.attachEvent('onclick', function(){this.DoSomething();});
和
row.addEventListener('click', function(){this.DoSomething();}, false);
当onclick事件引发,它调用你已经通过的匿名函数, 这个上下文是指引发事件的对象,而不是myObject 。 因为此时执行上下文在事件处理程序上下文中。
解决scheme:你可以做一个关于Mike Kantor的技巧,或者使用jQuery,使用代理方法来在匿名函数中定义这个上下文。
所以你的代码是这样的:
var myObject = { AddChildRowEvents: function(row, p2) { if(document.attachEvent) { row.attachEvent('onclick', $.proxy(function () { this.DoSomething(); }, this)); } else { row.addEventListener('click', $.proxy(function () { this.DoSomething(); },this), false); } }, DoSomething: function() { this.SomethingElse(); //<-- Error here, object 'this' does not support this method. } }
你已经提到这个错误是在this.SomthingElse()中 ,但是你的代码不会显示它。 如果你真的在这段代码中遇到错误,那么你可能会在其他地方使用方法DoSomthing作为事件处理程序。