最近になってprototype.jsの使い方を学んでみたりしているのですが、bind
とbindAsEventListener
についてちょっとした疑問が出てきています。
両者の違いについては、prototype.js v1.4.0 の使い方にある説明で知ることができました。サンプルソースを引用してみます。
<input type=checkbox id=myChk value=1> Test? <script> //declaring the class var CheckboxWatcher = Class.create(); //defining the rest of the class implementation CheckboxWatcher.prototype = { initialize: function(chkBox, message) { this.chkBox = $(chkBox); this.message = message; //assigning our method to the event this.chkBox.onclick = this.showMessage.bindAsEventListener(this); }, showMessage: function(evt) { alert(this.message + ' (' + evt.type + ')'); } }; var watcher = new CheckboxWatcher('myChk', 'Changed'); </script>
このbindAsEventListener
をbind
に変えてしまうと、Firefoxでは動作するのですがIEでは動作しなくなります(eventオブジェクトevtが未定義になるため)。要はbindAsEventListener
はブラウザ間の互換性を考慮した、イベントハンドラのためのbind
、ということなのだと解しました。
※ Hawk's Laboratory » prototype.js 1.4.0を読む:base.jsその2 にbindAsEventListener
とbind
の詳しい解説があります。
※ 更に、Hawk's Laboratory » attachEventの動作にて attachEvent
により渡される引数について調べて頂きました。
ただ、この例ではイベントハンドラの登録にonclick
プロパティを用いていますが、prototype.jsではEvent.observe
というイベントハンドラ追加用のメソッドも定義されています。なので、イベント登録の部分を
//assigning our method to the event
Event.observe(this.chkBox, 'click', this.showMessage.bind(this));
としてみると、bindAsEventListener
でなくbind
を使っているにも関わらず、IEでもFirefoxでも動作してました(Windows 2000のIE6とFirefox 1.5.0.3で確認)。
Event.observe
の実装を見てみると、DOM2 Event仕様にあるaddEventListener
が使えるときはそれを使い、そうでなければattachEvent
(IEでの実装)を使うようになっていました。それでattachEvent
について試してみたのですが、どうもattachEvent
でイベントハンドラを登録した場合には、イベントハンドラの引数としてイベントオブジェクトらしきものがちゃんと渡されているようです。
というわけで、イベントハンドラを登録するときはonXXXXX
のようなプロパティなぞを使わずに、(より標準っぽい)Event.observe
を使っておけば、bindAsEventListener
を使う必要はないのでは? という疑いを持ち続けています。しかしわざわざbind
と別にメソッドを定義しているのには何か理由があるのかもしれず、詳しい方の意見をお聞きしてみたいところなのです。