9

オブジェクトがそれをリッスンするようにイベントを作成しようとしています。次の例を考えてみましょう。

var moon;

moon = document.createEvent("Event");
moon.initEvent("Event",true,true);

var Dog = function (name) {
  this.name = name;
  
  document.addEventListener("Event",this.bark,false);
};
dog.prototype.bark = function() {
  console.log(this.name + ': Awooooooof Woof!');
};


var spot = new Dog("Spot");
var dot = new Dog("Dot");


//invoke
document.dispatchEvent(moon);

私は次のような出力を受け取ることを期待しています:

スポット:Awooooooof Woof!

ドット:Awooooooof Woof!

しかし、私が得るものは次のとおりです。

未定義:Awooooooof Woof!

私の例の何が問題になっていますか?Dogのすべてのインスタンスが持つリスナーを登録するにはどうすればよいですか?

4

3 に答える 3

10

この行で

document.addEventListener("Event",this.bark,false);

this.barkのスコープをにバインドしませんthis。JavaScriptでは、の値はthis関数が定義されている場所ではなく、関数が呼び出されている場所に依存します。これは、渡すときに現在のオブジェクトからデタッチすることthis.barkを意味します。addEventListener

protocol.jsやJQueryなどのフレームワークには、バインディングthisのショートカットがあります。バニラJavaScriptを使用すると、次のように実行できます。

function bind(scope, fn) {
   return function() {
      return fn.apply(scope, arguments);
   }
}

その後:

document.addEventListener("Event",bind(this, this.bark),false);
于 2013-03-12T09:36:36.323 に答える
4

あなたが持っている問題はthis、関数の内部があなたが操作したいオブジェクトを参照していないということです。

bark関数定義内に関数を追加するのはどうですか?

var Dog = function (name) {
    this.name = name;    
    this.bark = function() {
        console.log(name + ': Awooooooof Woof!');
    };
    document.addEventListener("Event", this.bark, false);
};
于 2013-03-12T09:31:44.367 に答える
0

問題

this内部のキーワードDog.prototype.bark()は、メソッドを呼び出したオブジェクトを指します。たとえば、spot.bark()が呼び出されると、次のようにthis.name評価されます。spot.name

Dog.prototype.bark = function () {
    console.log(spot.name + ': Awooooooof Woof!');
};

Dogのコンストラクター内にイベントリスナーが追加されると、documentオブジェクトはそのイベントをリッスンするように指示され、そのイベントをDog.prototype.bark()聞いたときに呼び出すように指示されます。この設定は正しく行われ、documentオブジェクトはそのイベントを聞くと正しい関数を呼び出します。

この問題は、後でdocumentオブジェクトが実際に樹皮関数を呼び出すときに発生します。ここで、オブジェクトをthisポイントし、次のように評価します。documentthis.namedocument.name

Dog.prototype.bark = function () {
    console.log(document.name + ': Awooooooof Woof!');
};

document.name存在しないため、出力は次のようになります。undefined: Awooooooof Woof!

修正

次のように、 Function.prototype.bind()を使用して、提供された値を関数のthisキーワードにバインドします。

document.addEventListener("Moon", this.bark.bind(this), false);
于 2016-09-21T19:55:12.820 に答える