4

私は何か間違ったことをしているのかもしれませんが、オブジェクト指向プログラミングを Javascript に適用しようとすると、興味深い動作が見つかりました。次のことを考慮してください

function Bug(element) {
    this.focusedCell = null;
    element.addEventListener('click', this.onClick, true);
};

Bug.prototype.onClick = function(event){
    console.log("this is: ");
    console.log(this);
};

コンソールからメソッドを呼び出すと、「this」の正しいインスタンスが表示されますが、ドキュメント内の要素をクリックすると、インスタンスの代わりにドキュメント要素が表示されます。だから...少なくとも私がやっているように、インスタンスメソッドでイベントリスナーを使用することはおそらく良い考えではありません。

質問は次のとおりです。

  • 呼び出しでインスタンスを保持しながら、javascript オブジェクトのインスタンス メソッドを呼び出すこのようなイベント リスナーを持つことは可能ですか?

  • これを行うためのより良いパターンはありますか?

編集:Chrome以外でこれを試したことはありません。しかし、動作は同じだと思います。

4

3 に答える 3

6

より良いパターンがあり、あまり変更する必要はありません。最初にコードを示します。

function Bug(element) {
    this.focusedCell = null;
    // --------------------------------v----pass the object, not a function
    element.addEventListener('click', this, true);
};

// Implement the `EventListener` interface
Bug.prototype.handleEvent = function(event) {
    if (event.type === "click")
        this.onClick(event);
}

Bug.prototype.onClick = function(event) {
    console.log(JSON.stringify(this));         // '{"focusedCell":null}'
    console.log(event.currentTarget.nodeName); // "DIV"
};

handleEventメソッドを追加することでBug、インターフェースを実装しEventListenerます。これにより、新しいBugオブジェクトをaddEventListener()関数の代わりに の 2 番目の引数として渡すことができます。

"click"イベントが発生すると、.handleEvent()メソッドが呼び出され、thisそのメソッドの値Bugがバインドされたオブジェクトになります。


thisはインスタンスへの参照であるため、明らかBugに要素への参照ではなくなります。ただし、要素は を介し​​て利用できるため、必須ではありませんevent.currentTarget

もちろん、必要にBug応じて、コンストラクターで要素をオブジェクトに直接追加することもできます。

デモ: http://jsfiddle.net/CnZTa/


于 2013-05-11T23:21:38.107 に答える
5

を使用して、必要なこの値にFunction.prototype.bindバインドされたリスナーを作成できます。

function Bug(element) {
    this.focusedCell = null;
    element.addEventListener('click', this.onClick.bind(this), true);
};

古い (非 ES5) ブラウザーには、MDNのようなポリフィルが必要です。

于 2013-05-11T23:22:00.227 に答える
1

これは JavaScript の通常の動作です。this関数をリスナーに渡すことで 、期待値を維持できます。

function Bug(element) {
    var self = this; // Store a reference to this
    this.focusedCell = null;
    element.addEventListener('click', function() {
        // in here this refers to element
        self.onClick(event);
    }, true);
};

Bug.prototype.onClick = function(event){
    console.log("this is: "); 
    console.log(this); // In here this refers the an instance of Bug.
};
于 2013-05-11T23:21:21.053 に答える