Consider this simple TS script
class foo {
v: number = 1;
public bar() {
console.log(this.v);
}
}
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
and the HTML
<html lang="en">
<body>
<button id="test">Test</button>
</body>
</html>
I would expect to get 2 lines console output of number "1".
But NO! I get one undefined
output
Lets take a look at the generated js file
var foo = (function () {
function foo() {
this.v = 1;
}
foo.prototype.bar = function () {
console.log(this.v);
};
return foo;
}());
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
//# sourceMappingURL=Test.js.map
For performance consideration TS decided to put the function on the prototype! so the addEventListener
call was actually adding the prototype (static) function twice and its the same instance. That's why I'm only getting one output instead of two.
And the biggest issue is that the this
inside the prototype function refers to the button and button doesn't contain a property called v
!
If we do this in native js
var foo = function () {
this.v = 1;
var that = this;
this.bar = function () {
console.log(that.v);
}
}
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
we would get the desire result!
Is this a known issue for TS where you can't use the class method as event handler?
And how can I remove that handler after I added it?