0

私の Web アプリケーションには、オブジェクト関数コンストラクターで定義したカスタム オブジェクトがあり、コンストラクター プロトタイプを介してさまざまな共有プロパティを適用しています。

MyObject = function (Name) {
  this.Name = Name;
  this.ListItem1 = document.createElement('li');
  this.ListItem1.onclick = this.SetActive;
  this.ListItem2 = document.createElement('li');
  this.ListItem2.onclick = this.SetActive;
}

MyObject.prototype.SetActive = function () {
  alert('SetActive: ' + this.Name);
}

これは簡単な例ですが、実際のオブジェクトにはさらに多くの DOM 要素が関連付けられており、それらの各 DOM 要素にはさまざまなイベント リスナーがあります。私のオブジェクトには、他にも多くのプロパティとメソッドがあります。このオブジェクトのインスタンスが何千もある可能性もあるため、コードの効率が重要です。

私の問題は、DOM イベントがトリガーされると、イベント ハンドラーの「this」プロパティが、オブジェクト インスタンスではなく、実際の DOM 要素に設定されることです。

例えば:

var HelloObj = new MyObject('Hello');
HelloObj.SetActive();    
    //This alerts 'SetActive: Hello'

HelloObj.ListItem1.click();    
    //This alerts 'SetActive: undefined' because 'this' in SetActive
    //becomes ListItem1 and obviously ListItem1.Name is undefined

では、DOM 要素のイベント ハンドラーを関数ポインター (多数のオブジェクト インスタンスがある場合に非効率になる各イベント ハンドラーの新しい関数インスタンスではない) に設定し、オブジェクト インスタンス自体のコンテキストを保持するにはどうすればよいですか? 'これ'?

4

2 に答える 2

1

このようにしてみてくださいbind()

this.ListItem1.onclick = this.SetActive.bind(this); 
//and so on
于 2013-03-28T16:44:31.640 に答える
0

私が思いつき、現在使用している解決策は、オブジェクト インスタンスへの参照を DOM 要素にアタッチし、イベント ハンドラーのラッパー関数を使用して、その参照を通じて目的の関数を呼び出すことです。

MyObject = function (Name) {
  this.Name = Name;

  this.ListItem1 = document.createElement('li');
  this.ListItem1.Context = this;
  this.ListItem1.onclick = this.SetActiveHandler;

  this.ListItem2 = document.createElement('li');
  this.ListItem2.Context = this;
  this.ListItem2.onclick = this.SetActiveHandler;
}

MyObject.prototype.SetActiveHandler = function () {
  this.Context.SetActive();
}
MyObject.prototype.SetActive = function () {
  alert('SetActive: ' + this.Name);
}

これですべての問題が解決しますが、いくつかの落とし穴があるため、完全に満足しているわけではありません。視覚的にはそれほどきれいではなく、より複雑です。プログラム的には循環参照を作成しますが、これは一般的に嫌われていることを知っていますが、私の状況では、最新のブラウザーについてのみ心配しているため、問題が発生することはないと思います。ドキュメントからすべての DOM 要素が削除され、MyObject 自体のインスタンスへの参照を削除しました。すべてを完全にガベージ コレクションする必要があります (これに関するフィードバックをいただければ幸いです)。また、カスタム プロパティを DOM 要素にアタッチすることも悪い習慣と見なされていることはわかっていますが、それが最新のブラウザーでまだ問題になっているかどうかはわかりません (繰り返しますが、いくつかのフィードバックは素晴らしいでしょう)。また、2 番目の関数を使用する必要があるため、オブジェクト指向のフローが少し中断されます。イベント ハンドラを直接SetActive().

誰かが他の解決策を持っていますか、または私が解決しているよりも多くの問題を実際に作成しているかどうかに光を当てることができますか?

于 2013-03-28T18:56:59.733 に答える