2016-10-21 4 views
2

これは、How to access the correct `this` context inside a callback?の複製ではありません。メンバ関数をイベントリスナーとして使用するためのES6ショートカットはありますか?

回答の一部は、the Question is differentと似ている可能性があります。以下のコメントから答えが分かります。これは、ES6の古いJavaScriptではないため、さまざまな解決策があります。この質問はコールバックではなく、イベントリスナーに関するものです。そのようなものには、プレーンコールバックには適用されない他の解決策があります。私はクラスを持っていると私はいくつかのイベントが定型

class SomeClass { 
    constructor(msg, elem) { 
    this.msg = msg; 
    elem.addEventListerer('click', (...args) => { // Can these 
     this._onClickListener(...args);    // three lines 
    });           // be simpler? 
    } 
    _onClickListener() { 
    console.log(this.msg); 
    } 
} 

の束を書くことに私が持っ終わるそのクラス内の関数を呼び出すようにしたい場合は


使用するためのいくつかのES6糖衣構文がありますリスナーとしてのクラスメソッド理想的には私は

class SomeClass { 
    constructor(msg, elem) { 
    this.msg = msg; 
    elem.addEventListener('click', this._onClickListener); 
    } 
    _onClickListener() { 
    console.log(this.msg); 
    } 
} 

ような何かをできるように好きで、それが正しくthisを設定し、関係なく、イベントのすべての引数を渡す必要があるだろう。

しかし、それは動作しません。ボイラープレートなしでthisが設定されていません。

class SomeClass { 
 
    constructor(msg, elem) { 
 
    this.msg = msg; 
 
    elem.addEventListener('click', this._onClickListener); 
 
    } 
 
    _onClickListener() { 
 
    console.log(this.msg); // this is wrong 
 
    } 
 
} 
 

 
var s = new SomeClass("hello", document.querySelector("button"));
<button>click me</button>

+0

を削除することができるということです私はES6の何かに精通していませんが、あなたはESW(ECMAScript Whatever)デコレータで何かをするかもしれません。 –

+0

一般的には、イベントリスナーのコールバックで 'this'を要素にすることが望ましいでしょう。 – adeneo

+0

EventListenerインターフェイスは、これを処理するための素晴らしい方法を提供します:https://jsfiddle.net/ysLd6L35/ –

答えて

5

をあなたはコンテキストをバインドする必要があります。

class SomeClass { 
    constructor(msg, elem) { 
    this.msg = msg; 
    this._onClickListener = this._onClickListener.bind(this); 
    elem.addEventListener('click', this._onClickListener); 
    } 
    _onClickListener() { 
    console.log(this.msg); 
    } 
} 
このソリューションの

追加の利点は、あなたが、私は「リスナーelem.removeEventListener(this._onClickListener)

+0

ああ!脳のおなら。なぜ私は 'bind'について忘れたのか分かりません。面白いのは、ローカルバインドされたメソッドを追加することです。私は、バインドされた関数への参照を持っているので、後でリスナーを簡単に削除できるという利点があると思います。 – gman

+0

@gman:とにかくES6構文を使用している場合は、 '.bind()'を使う必要はありません。 'elem.addEventListener(" click、event => this._onClickListener()) '矢印関数は' this'が定義されていないので、外部の字句環境から取得します。 –

+0

@squint:あなたの例を理解すれば、それは任意の引数を渡すつもりはありませんか? 'バインド'が行われます。 – gman

2

class SomeClass { 
 
    constructor(msg, elem) { 
 
    this.msg = msg; 
 
    elem.addEventListener('click', this._onClickListener.bind(this)); 
 
    } 
 
    _onClickListener() { 
 
    console.log(this.msg); 
 
    } 
 
} 
 

 
var s = new SomeClass("hello", document.querySelector("button"));
<button>click me</button>

私はあなたを理解し、完全ではないかもしれませんが、それはbindで動作します。

基本的には、bindは常に指定した参照に設定thisにバインドされた関数のコピーを作成します。 (また、引数をバインドすることができますが、それはこの場合には無関係です。)

+0

さて、私は前に 'bind'を使っていました。私がなぜ忘れたのか分かりません:P Doh! – gman

関連する問題