Overwritten “this” variable problem or how to call a member function?

断了今生、忘了曾经 提交于 2019-12-18 09:37:30

问题


I have this class where I am using a combination of jQuery and 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
    }
});

How can I call this.updateSum() after all?


回答1:


You need to use closures.

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



回答2:


Totally untested suggestion:

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

.bind() gives back a new function where the first parameter of bind is closured for you as the function's this context. It can also closure parameters, check out the documentation.

To me, Function.bind() is the single best function ever written in JavaScript :)




回答3:


DOMEvent handlers are traditionally called with the elements they're registered to as context / "this". This is what jQuery does, too.

The easiest option for you would be to use jQuery's ability to handle event data

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

The other possibility is to use closures to define the updateHandler inside the constructor

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

This is a working example what one of the other answers tried to do. It works because the anonymous function can always access the variables in the surrounding function -- but it only works if the function is really defined in the function that has "that" as local variable.




回答4:


It is the famous Javascript idiom you need to use in initElements function:

var that = this;

Later in your handler just refer to that instead of 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
    }
});

It was covered in great detail in talk by Stuart Langridge on Javascript closures at Fronteers 2008 conference.



来源:https://stackoverflow.com/questions/737454/overwritten-this-variable-problem-or-how-to-call-a-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!