As I checked on MDN, method of a class looks like this:
class Foo {
method1 (){
// content of method1
}
}
However I found it's not good for event handlers
<!doctype html>
<html lang="en">
<head>
<title>test</title>
</head>
<body>
<div class="settings">
<div>
<label for="cb1">checkbox</label>
<input id="cb1" type="checkbox"></input>
</div>
</div>
<script>
'use strict'
class TEST{
box = null;
info = {content: {blah: "blah"}};
init (){
this.box = window.document.querySelector(".settings");
this.box.addEventListener("change", this.handler);
this.box.addEventListener("change", this.handler2);
}
handler = e=> {
console.log("handler this: %o", this);
console.log("handler info: %o", this.info.content);
}
handler2 (e) {
console.log("handler2 this: %o", this);
console.log("handler2 info: %o", this.info.content);
}
}
let t = new TEST();
t.init();
</script>
</body>
</html>
In the test page above, click the checkbox then the result is
Reading about arrow function's scope then I understand why ther's the difference. But using arrow function to declare a method of class looks weird, did I do it correctly?
What's more since I don't like there're two kind of function style in one class, I prefer using arrow function for all other methods if possible, but I'm not sure this works for constructor
or did it has any potential glitch or secure problem
Any opinion on this please?
But using arrow function to declare a method of class looks weird, did I do it correctly?
Yes, this works, but notice they are arrow functions in class fields and not methods.
What's more since I don't like there're two kind of function style in one class, I prefer using arrow function for all other methods if possible, but I'm not sure this works for constructor or did it has any potential glitch?
Yes, you cannot use this style for the constructor
, and you should not generally use this because it doesn't work properly with inheritance (cannot be overridden properly, cannot be used with super
) and uses more memory than a shared prototype method - the arrow functions are created per instance.
So use this only where you really need it. Alternative approaches are
creating the arrow functions explicitly in the constructor, without class field syntax:
class TEST {
constructor() {
this.box = null;
this.info = {content: {blah: "blah"}};
this.handler = e => {
console.log("handler this: %o", this);
console.log("handler info: %o", this.info.content);
};
}
init() {
this.box = window.document.querySelector(".settings");
this.box.addEventListener("change", this.handler);
this.box.addEventListener("change", this.handler2);
}
handler2(e) {
console.log("handler2 this: %o", this);
console.log("handler2 info: %o", this.info.content);
}
}
defining methods and .bind()
ing them explicitly in the constructor:
class TEST {
box = null;
info = {content: {blah: "blah"}};
constructor() {
this.handler = this.handler.bind(this);
}
init() {
this.box = window.document.querySelector(".settings");
this.box.addEventListener("change", this.handler);
this.box.addEventListener("change", this.handler2);
}
handler(e) {
console.log("handler this: %o", this);
console.log("handler info: %o", this.info.content);
}
handler2(e) {
console.log("handler2 this: %o", this);
console.log("handler2 info: %o", this.info.content);
}
}