[JavaScript]addEventListenerで不意をつかれた話

最近はASでthisなんて使ってなかったから、こんな挙動だったなんて思っていませんでした。

という話です。

クラスのメソッドをハンドラにしたらthisが変わってた

クラス内で自身のプラパティやメソッドを参照する際にthisを使うのですが、以下のソースの用に書くとthisが変わっていらっしゃいました。

var A = function()
{
 this.p = 'test';
};
A.prototype.handler = function(event)
{
 console.log(this.p);
};
a = new A();
document.body.addEventListener('test', a.handler);
document.body.dispatchEvent(new Event('test')); //this.p == undefind
a.handler(); //this.p == 'test'

イベントを経由した場合thisがdocument.bodyになるため、this.pが参照できなくなります。困っちゃいます。

thisの参照をaにする

addEventListenerの際に、a.handler.bind(a)とする事でthisをaにする事が出来ます。

document.body.addEventListener('test', a.handler.bind(a));
document.body.dispatchEvent(new Event('test')); //this.p == 'test'
a.handler(); //this.p == 'test'

 

イベントを経由してもthisがaのままです。

ただ、これだとremoveEventListenerが出来ないようです。

document.body.addEventListener('test', a.handler.bind(a));
document.body.dispatchEvent(new Event('test')); //this.p == 'test'
document.body.removeEventListener('test', a.handler.bind(a));
document.body.dispatchEvent(new Event('test')); //this.p == 'test'(処理されてしまう)

ちょっと書き方を考える必要がありそうですね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>