何らかの理由で、es6クラスの "this"に奇妙な値を取得しています...
'use strict';
class Clicker {
constructor(element) {
this.count = 0;
this.elem = element;
this.elem.addEventListener('click', this.click);
// logs Clicker { count:0, elem: button#thing} as expected
console.log(this);
}
click() {
// logs <button id="thing">...</button> as unexpected...
console.log(this);
this.count++;
}
}
var thing = document.getElementById('thing');
var instance = new Clicker(thing);
<button id="thing">Click me</button>
なぜクリッカーのクリックメソッド内の「this」が...自体ではなくdomノードを参照するのですか?
さらに重要なのは、「this」を使用してクリックできない場合に、クリックメソッド内からクリッカーのカウントプロパティを参照するにはどうすればよいですか。
なぜクリッカーのクリックメソッド内の「this」が...自体ではなくdomノードを参照するのですか?
.addEventListener()
の仕様では、this
ポインターをイベントをキャッチしたDOM要素に設定するためです。それが動作するように設計されている方法です。
this
の値をオーバーライドするコールバックとしてメソッドを渡す場合、.bind()
を使用してthis
の目的の値を強制できます。
_this.elem.addEventListener('click', this.click.bind(this));
_
説明:
JavaScriptのすべての関数呼び出しは、関数の呼び出し方法に応じてthis
の新しい値を設定します。基本的なルールセットの詳細については、 この説明 を参照してください。
それに加えて、これを行うと:
_this.elem.addEventListener('click', this.click);
_
_this.click
_メソッドを取得し、そのメソッドだけをaddEventListener()
に渡すだけです。 this
の値は完全に失われます。あなたがこれをしているようです:
_var m = this.click; // m here is just a reference to Clicker.prototype.click
this.elem.addEventListener('click', m);
_
さらに、.addEventListener()
は、コールバックを呼び出すときにthis
の独自の値を設定するために(イベントを作成する要素でthis
を指すように)特別に構築されます。
したがって、上記の.bind()
を使用して、メソッドが呼び出されたときにthis
の適切な値を強制的に設定できます。
参考のために、Javascriptでの関数呼び出しが役立つために this
が設定される6つの方法のこの説明 を見つけることができます。
その他のオプション
.bind()
がこれを定義する最も明確な方法であると思いますが、ローカルの匿名関数を使用することもできます。
_var self = this;
this.elem.addEventListener('click', function() {
self.click();
});
_
またはES6では、矢印関数:
_this.elem.addEventListener('click', () => this.click());
_
前の例で使用したthis
参照が不要になるように、矢印関数はself
の値を自動的に保存します。