web-dev-qa-db-ja.com

EventEmitterを拡張するES6クラス定義でイベントリスナーを設定します

クラスのdefinitionですでに定義されている定義済みのカスタムリスナーが必要です(ビルドイン 'newListner' イベント)。そのため、コンストラクターでそれらをバインドするだけでは不十分です。これは、そのクラスの新しいインスタンスごとに実行されるためです。

これを行う方法?プロトタイプを変更しますか?それは可能ですか?

私がこれまでに持っているもの:

class Cat extends EventEmitter {
  // just added for demonstration, I don't want this!
  constructor() {
    super();
    // does fire
    this.on('wave', function() { console.log('constructor wave'); });
  }
}
// compiles but does not fire
Cat.prototype.on('wave', function() { console.log('prototype wave'); });

var cat = new Cat();
cat.emit('wave');
9
flori

インスタンスごとにリスナーを個別に登録することは避けられません。そのための自然な場所はコンストラクターです。1、2。ただし、新しいリスナー関数の作成を回避できます。

class Cat extends EventEmitter {
  constructor() {
    super();
    this.on('wave', this.onWave);
  }
  onWave() {
    console.log('prototype wave');
  }
}

var cat = new Cat();
cat.emit('wave');

1:._eventsのゲッターのような他の方法があります。 「デフォルト」リスナーの典型的な継承を含め、これを使用してあらゆる種類の凝ったことを行うことができますが、それらは完全に複雑で、すぐに頭を乗り越えます。コンストラクターにいくつかの汎用コードを配置するだけで、凝ったことも(そしてはるかにクリーンに)行うことができます。
2:EventEmittersのinitメソッドをオーバーライド(特殊化)することもできますが、まったく同じになります。

9
Bergi

私が見る限り、Catエミッターの複数のインスタンスは相互に通信できないため、コンストラクターに各インスタンスのリスナーを登録する必要があります。

class Cat extends EventEmitter {
  constructor() {
    super();
    this.on('wave', function() { console.log('constructor wave'); });
  }
}

var cat = new Cat();
cat.emit('wave');

その後、必要なスクリプトにrequireすることで、エミッタインスタンスをさまざまなファイル全体でいつでも共有できます。

0
nils