関西での JavaScript 勉強会、Kanasan.JS に行ってきた。内容は Prototype.js のコードリーディング (バージョン 1.5.1.1 を使用)。「家に帰ってレポートを書き、主催者のブログにトラックバックを送るまでが勉強会です」と念を押されたので、まもなく Kanasan さんの記事経由で参加者各々の様子をうかがえるようになると思うけど、以下あとから思ったことも加えて私の場合をつらつらと。
やはり皆さん一番引っかかるのはここみたい。おそらく、プロトタイプと名のつくものが 2 つあるのが混乱の原因だと思う。
prototype
プロパティ[[Prototype]]
内部プロパティ[[Prototype]]
内部プロパティに指定されているオブジェクト、さらにその [[Prototype]]
内部プロパティに指定されているオブジェクト、……といった具合に、そのプロパティ / メソッドが見つかるまでプロトタイプチェーンをたどることになる。内部プロパティなので普通に JavaScript コードを書いているときに参照はできないが、__proto__
プロパティとして公開している実装 (Firefox で使われている SpiderMonkey、Safari で使われている JavaScriptCore など) もある。prototype
プロパティと [[Prototype]]
内部プロパティの関係については、私も以前 JavaScript の new 演算子の意味で少し触れたほか多くの解説記事があるし、これを押さえておくと JavaScript の理解がぐっと進むと思う。Prototype.js を読む上でも、今追加しているのがいわゆるクラスメソッドなのかインスタンスメソッドなのかといったことがわかりやすくなるだろうし。
JavaScript はレキシカルスコープを採用。関数内で定義されていない変数が実際にどの変数を指しているか、静的に (コンパイル時に) 決定できるのがレキシカルスコープ、実行時にならないとわからないのがダイナミックスコープ。
Perl でいうと、my
で定義された変数 (Private Variables via my() の項) はレキシカルスコープを持ち、local
で定義された変数 (Temporary Values via local() の項) はダイナミックスコープを持つ (個人的には my と local どう違う? - futomi's CGI Cafe の例がわかりやすかった)。Common Lisp はレキシカルスコープだが、Emacs Lisp は (レキシカルスコープにすると重くなるから) ダイナミックスコープらしい。
Prototype.js ではブラウザが Opera かどうかの判別に window.opera
の有無を用いている。Opera では Opera オブジェクトが window.opera
プロパティの値。Opera オブジェクトは、"9.23"
といったバージョンを文字列で返す version
メソッドなどを持つ。
Prototype.K
名前の由来が謎。K コンビネータ説は motemen さんより。やってることは
セコメントをする