Why does "this" inside the Clickers click method refer to the dom node and not ... itself?
Since the specification for .addEventListener() is to set the this pointer to the DOM element that caught the event. This is how it is designed to work.
When passing a method as a callback where you want to override this , you can use .bind() to force it to this :
this.elem.addEventListener('click', this.click.bind(this));
Explanation:
All function calls in Javascript set a new this value according to how the function is called. See this explanation for more information on this basic rule set.
Also, when you do this:
this.elem.addEventListener('click', this.click);
You simply get the this.click method and pass this method only addEventListener() . The value of this will be completely lost. As if you are doing this:
var m = this.click;
In addition, .addEventListener() specifically designed to set its own this value when it calls a callback (to point this to the element that creates the event).
So, you can use .bind() as shown above to force the correct this value when calling the method.
For reference, you can find this description of six ways to configure this for a useful function call in Javascript.
Other options
I find .bind() be the clearest way of defining this, but you can also use either a local anonymous function:
var self = this; this.elem.addEventListener('click', function() { self.click(); });
or in ES6, arrow function:
this.elem.addEventListener('click', () => this.click());
The arrow function will store the this value so that you automatically avoid using the self link used in the previous example.