いくつかのこと:
var self = this
ほとんどの人は、速くて簡単なので、のようなものを提案します。
ただし、ビューオブジェクトをビューロジックから完全にvar self = this
分離するわけではありません。ビューロジックは、より正式なC#の背景から来ており、コードを見ると、やりたいことのように聞こえます。
イベントが発生したときにのみコールバックを実行するには、ハンドラーを関数でラップして、すぐに評価されるようにしますが、keydown
イベントが発生したときにのみ実行されます(以下のコードを参照)。
JSのスコープを理解する:実行コンテキストが何であれ、現在のスコープでもあります。リスナーはのメソッド(と呼ばれるlisten
)に追加されましたKeyboard.prototype
が、keydown
イベントは実際にはwindow
で発生します。ハンドラーは、定義された場所とは異なるコンテキストで実行されています。呼び出し元のコンテキスト内で実行されているため、この場合は、定義されたときに、または定義されたときに別のオブジェクトにバインドしない限り、window
スコープが適用されます。window
bind
apply
コードでwindow
は、はユーザーが操作しているビューであり、Keyboard
はそのビューのコントローラーです。C#/。NETでおそらく慣れているようなMVCパターンでは、ビューは何かが起こったときに何をすべきかを自分自身に伝えず、コントローラーはビューに何をすべきかを伝えます。var self = this
したがって、多くの場合と同じようにコントローラーへの参照を割り当てる場合、ビューはそれ自体を管理しますが、keydown
イベントの特定のハンドラーに対してのみです。これは一貫性がなく、大規模なプロジェクトでは管理が難しくなります。
解決策:
Keyboard.prototype.listen = function() {
window.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
}
より良い解決策:
Keyboard.prototype.view = window;
Keyboard.prototype.listen = function() {
this.view.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
}
最善の解決策(ES6のclass
準備が整うまで):
// define
function addViewController(view) {
function ViewController() {
this.handle_keydown = function(args) {
// handle keydown events
};
this.listen = function() {
this.view.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
};
this.view = view;
return this;
}
return new ViewController(view);
}
// implement
var keyboard = addViewController(window);
keyboard.listen();
- 注:
.bind()
ECMAScript5+と互換性があります。古いブラウザのソリューションが必要な場合は、Mozillaがandを.bind()
使用する代わりの優れた方法を投稿しています。functions
.call()
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
編集:keyboard
この新しいモジュラーソリューションを使用すると、インスタンス化されたオブジェクトは次のようになります。