Call of object.method from event gets empty object

Posted on
  • I do not have much experience with JavaScript (have quite a bit with Java).
    It is weird issue from my perspective. If I assign an object's method call to event, it runs in empty object instance. All fields are empty. But if I wrap object's method into a function, and put into event, it runs ok. Is it normal?
    Example:

    const O = {
      A:"", B:0,
      M : function(){
        this.A = this.A + "*";
        this.B = this.B + 1;
        print(this.A," - ", this.B);
      }
    };
    
    function F(){
      O.M();
    }
    
    // uncomment one  or another call and run
    //setInterval(O.M, 1000); // method M runs in empty object instance
    //setInterval(F, 1000); // method M runs in populated object instance
    

    Output of direct method assignment

    undefined*  -  NaN
    undefined**  -  NaN
    undefined***  -  NaN
    

    Output of wrapped method assignment

    *  -  1
    **  -  2
    ***  -  3
    
  • Yes, this is normal.
    This looked right to me when I read your question, but didn't really know why so I looked it up. I think this explains it better than I can: https://developer.mozilla.org/en-US/docs­/Web/API/setTimeout#the_this_problem

  • yes, it's because this is set based on how the function is called.

    O.M(); // this==O
    
    var A = {};
    A.M = O.M;
    A.M(); // this==A
    
    var f = O.M();
    f(); // this==undefined <- what is happening with setInterval
    

    You can always just do:

    setInterval(() => O.M(), 1000)
    
  • Thank you myownself and Gordon! Will know.

    setInterval(() => O.M(), 1000) - looks cool
    
  • Mark_M

    this is an alternative of 'wrapping' - .bind() :

    const O = {
      a:"", b:0,
      m : function(){
        this.a = this.a + "*";
        this.b = this.b + 1;
        print(this.a," - ", this.b);
      }
    };
    var O_M = O.m.bind(O); // binding O as context for 'this' in function / method m
                          // returns a new function with the right context set of this for O.
    
    setInterval(O_M,1000);
    

    For Function.prototype.bind() see https://developer.mozilla.org/en-US/docs­/Web/JavaScript/Reference/Global_objects­/Function/bind (and take also a look at the referenced .apply(...) ).

    Btw, in JS same upper/lower/camel-casing as Java is useful. Constructor functions - like Classes in Java (and other 'like-minded' languages) - have an uppercase initial.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Call of object.method from event gets empty object

Posted by Avatar for Mark_M @Mark_M

Actions