You are reading a single comment by @Robin and its replies. Click here to read the full conversation.
  • 'However, I cannot emit an event within a prototype function with 'this''

    After playing with these snippets, I'm now not entirely sure what the original intent is/was.

    http://www.espruino.com/Reference#l_Object_on

    In post #2 L6, registers an arrow function response to object a

    Missing, following L8 is the event listener registration for object a1

    So when L9 executes, there isn't the registered listener to respond to the console.


    'Thus if e.g. I have two step up modules, I cannot subscribe directly to each of them'

    It is possible that as the second 'Got event' never occurs, (comment L9) compared to the test results in post #1 is just simply tripping up thinking, as there isn't a means (an on() method attached to a1) to view the second event?

  • Many thanks, Robin! However, seems that this correctly references the instance, also supported by stackoverflow answer:

    Arrow functions do not have a this value of its own, when you access it, you are accessing the this value of the enclosing lexical scope.

    We can see if we print it out:

    function aClass(id) {
      this.id = id;
    }
    
    aClass.prototype.testEmit = function() {
      setTimeout(()=>{console.log('This is ', this); this.emit('TestEvent')}, 1000); 
    };
    
    var a = new aClass('a');
    a.on('TestEvent', ()=>console.log('a emitted')); 
    a.testEmit();  // get 'This is aClass {id = a...}' and the event is caught with 'a emitted' 
    
    var a1 = new aClass('a1');
    a1.on('TestEvent', ()=>console.log('a1 emitted')); 
    a1.testEmit(); // get 'This is aClass {id = a1...}' and the event is caught with 'a1 emitted' 
    

    By contrast, if we replace arrow function in L6 with function(), this will reference the global object, which does not have emit(), and code crashes.

    setTimeout(function(){console.log('This is ', this); this.emit('TestEvent')}, 1000);  //crashes
    

    To summarize for reference, this can be used, but should be cautious when calling setTimeout:

    function aClass() {}
    
    aClass.prototype.testEmit = function() {
      this.emit('TestEvent'); 
    };
    
    var a = new aClass();
    var a1 = new aClass();
    
    a.on('TestEvent', ()=>console.log('a emitted')); 
    a1.on('TestEvent', ()=>console.log('a1 emitted')); 
    
    setTimeout(a.testEmit.bind(a), 500); // can use, get printed 'a emitted'
    setTimeout(()=>a1.testEmit(), 1000); // can use, get printed 'a1 emitted'
    
    setTimeout(a.testEmit, 1500); //crashes, as *this* in testEmit definition references global object, not a
    
    
About

Avatar for Robin @Robin started