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

前端 未结 4 1225
小鲜肉
小鲜肉 2020-12-21 23:16

I have this class where I am using a combination of jQuery and Prototype:

var MyClass = Class.create({
    initElements: function(sumEl) {
       this.sumEl          


        
相关标签:
4条回答
  • 2020-12-21 23:38

    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.

    0 讨论(0)
  • 2020-12-21 23:44

    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.

    0 讨论(0)
  • 2020-12-21 23:49

    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 :)

    0 讨论(0)
  • 2020-12-22 00:00

    You need to use closures.

     initElements: function(sumEl) {
            this.sumEl = sumEl;
            var ref = this;
            sumEl.keyup( function(){ref.updateSumHandler();});
     },
    
    0 讨论(0)
提交回复
热议问题