handling of this strange(?)

Posted on
  • trying this, I would expect an errormessage for incrementing a.
    In Espruino, a is incremented twice, and in log there is 1 3 5 ....21 23
    But by typing console.log(b.a) thje answer is 0, always.
    I'm confused, so is the problem on my side or is it Espruino ?

    function test(){
      var interval;
      this.a = 0;
      interval = setInterval(function(){
          a++;
          this.a++;console.log(a,this.a);
        },2000);
    }
    var b = new test();
    
  • That's some dodgy code to me. Did you try to run it somewhere else? I did in my browser and I think it's not working like you would expect it. Unless its only purpose is to fail :)

  • Ah so I've just noticed that you are saying that it is NOT failing.
    Is it possible that test() function was called beforehand during your tests? I don't fully understand what is going on there but maybe that's where your a values are coming from. And b.a in that case would always be 0.

  • I've had the problem in a big function and reduced to show the problem.
    Simple example for the need could be to

    • have a blinker running
    • need the status of the blinker somewhere else in your code
      Right now I help my self using a get-function, instead of b.a
      Any handling of a (line 5 and 6) should cause an error in my understanding.
      In jsfiddle it does.
      Before running this short example my board(32STMF4Discovery) was disconnected and "reset();" was sent in terminal window, before transfering the source above.
  • When I run your code I get:

    1 1
    3 3
    5 5
    7 7
    9 9
    11 11
    etc
    

    and if I type dump() I get:

    function test() {
      var interval;
      this.a = 0;
      interval = setInterval(function(){
          a++;
          this.a++;console.log(a,this.a);
        },2000);
    }
    var b = {"a":0};
    var a = 13;
    setInterval(function () {
          a++;
          this.a++;console.log(a,this.a);
        }, 2000);
    

    So what's happening is that the setInterval is being run in the root scope (as 'this' isn't set for intervals iirc). That means that 'a' refers to a in the root scope, and 'this'==root, so this.a is exactly the same thing.

    In Espruino a++ doesn't create an error if a doesn't exist, it just creates a locally in the function. Maybe that's not spec compliant and it could be changed in the future, but IMO soldiering on when there is no need to fail isn't very high priority.

    There may be something strange with the handling of scopes for intervals I guess. If you can come up with a simple test that works in jsconsole/jsfiddle but that doesn't work in Espruino then I'll try and track it down though.

    By the way, even if you delete the offending line a++, your code still doesn't work in something like jsconsole (it outputs NaN).

  • Just to add, if you do:

    function test(){  
      var interval;
      console.log(this);
      this.a = 0;
      interval = setInterval(function(){
          this.a++;console.log(this,this.a);
        },2000);
    }
    var b = new test();
    

    and compare, it looks like this is handled fine. The issue is that undefined+1 (and hence this.a++) returns NaN in other JS implementations, but in Espruino it just returns 1. I'll make a bug for that, and also for a++ errors so at least we can track it.

    bugs:

    https://github.com/espruino/Espruino/issues/146
    https://github.com/espruino/Espruino/issues/147

  • Thanks for the explanation.
    After adding var me = this, and using me instead of this, it works fine now (at least for my need).
    I agree to you, priority of this is not high.
    BTW, maybe something like "use strict" is an option (?)

  • I'd prefer just to add the error I think - something like "use strict" will just be more complication in the interpreter, and I doubt it will be used by too many people.

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

handling of this strange(?)

Posted by Avatar for JumJum @JumJum

Actions