覆盖“this”变量问题或如何调用成员函数?

我有这个类,我使用jQuery和Prototype的组合:

var MyClass = Class.create({ initElements: function(sumEl) { this.sumEl = sumEl; sumEl.keyup(this.updateSumHandler); }, updateSumHandler: function(event) { // Throws error here: "this.updateSum is not a function" this.updateSum(); }, updateSum: function() { // does something here } }); 

我怎么能调用this.updateSum()呢?

你需要使用闭包。

  initElements: function(sumEl) { this.sumEl = sumEl; var ref = this; sumEl.keyup( function(){ref.updateSumHandler();}); }, 

完全未经测试的建议:

 sumEl.keyup(this.updateSumHandler.bind(this)); 

.bind()返回一个新函数,其中bind的第一个参数作为函数的上下文关闭。 它还可以关闭参数,查看文档 。

对我来说, Function.bind()是用JavaScript编写的唯一最好的函数:)

传统上,DOMEvent处理程序使用它们注册为上下文/“this”的元素进行调用。 这也是jQuery的function。

最简单的选择是使用jQuery处理事件数据的能力

 var MyClass = Class.create({ initElements: function(sumEl) { this.sumEl = sumEl; sumEl.bind("keyup", this, this.updateSumHandler); }, updateSumHandler: function(event) { // event.data is the initial this // call updateSum with correct context event.data.updateSum.call(event.data); }, updateSum: function() { // does something here } }); 

另一种可能性是使用闭包来定义构造函数中的updateHandler

 var MyClass = Class.create({ initElements: function(sumEl) { this.sumEl = sumEl; // save this as that so we can access it from the anonymous function var that = this; sumEl.keyup(function() { that.updateSum(); }); }, updateSum: function() { // does something here } }); 

这是其他一个答案试图做的一个工作示例。 它的工作原理是因为匿名函数总是可以访问周围函数中的变量 – 但它只有在函数中具有“that”作为局部变量的函数中才有效。

这是你需要在initElements函数中使用的着名的Javascript习语:

 var that = this; 

稍后在你的处理程序中只需引用that而不是:

 var MyClass = Class.create({ initElements: function(sumEl) { this.sumEl = sumEl; var that = this; sumEl.keyup(this.updateSumHandler); }, updateSumHandler: function(event) { that.updateSum(); }, updateSum: function() { // does something here } }); 

Stuart Langridge在Fronteers 2008大会上关于Javascript关闭的 演讲中详细介绍了这一点。