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

时间:2009-04-10 12:17:25

标签: javascript jquery oop event-handling prototypejs

我有这个类,我使用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()

4 个答案:

答案 0 :(得分:5)

你需要使用闭包。

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

答案 1 :(得分:4)

完全未经测试的建议:

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

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

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

答案 2 :(得分:1)

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

最简单的选择是使用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”作为局部变量的函数时才有效。

答案 3 :(得分:0)

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

var that = this;

稍后在您的处理程序中,只需引用that而不是this

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
    }
});

在Fronteers 2008大会的 Javascript closures talk by Stuart Langridge中详细介绍了这一点。