TypeScript(またはJavaScript)で EventTarget.addEventListener()
を使用する場合、第2引数の指定方法によって実行時の this
の中身が変わります。
今更ながら地味にはまったため、自分用にメモしておきます。
確認
確認用にコードを作成しました。
https://playcode.io/671961
EventTarget.addEventListener()
第2引数の指定方法によって、関数show 実行時の this
は以下のようになります。
script.ts
class ThisTest {
constructor() {
this.bindEvent();
}
// この関数を呼び出して、thisの中身を判定する。
show(e: Event) {
console.log(this.constructor.name);
}
bindEvent() {
const t1 = document.querySelector('#test1');
t1.addEventListener('click', this.show);
// => 'HTMLButtonElement'
const t2 = document.querySelector('#test2');
t2.addEventListener('click', this.show.bind(this));
// => 'ThisTest'
const t3 = document.querySelector('#test3');
t3.addEventListener('click', (e: Event) => this.show(e));
// => 'ThisTest'
const t4 = document.querySelector('#test4');
t4.addEventListener('click', function (e: Event) {
console.log(this.constructor.name);
// => 'HTMLButtonElement'
this.show(e);
// => 'error: Uncaught TypeError: this.show is not a function'
// this.show(e)の `this` がボタン要素を示すため、エラーが発生する。
});
}
}
new ThisTest();
index.pug
button#test1 テスト1
button#test2 テスト2
button#test3 テスト3
button#test4 テスト4
所感
EventTarget.addEventListener()
に限った話ではないですが、はまらないように注意したいですね。