読 prototype.js 感想文
prototype.js のコードを読んでみると、いろいろなことに気づきます。Javaを使い続けて凝り固まったアタマには、いい刺激になりました。小学生の読書感想文レベルですが、思ったこと書いてみます。
以前のエントリで書いた、コード例。
//paneにappendしたノードを全削除。
$A( $('pane').childNodes ).each(
function(node){
node.remove();
}
);
まず私は、このコードを見て、「ほほー、JavaScriptは自信の文法を変えることができるのかぁ」なんて、知ったかぶりして、思ったのです。最近は、Rubyの台頭も手伝って、オリジナル言語ブーム(?)ですし、prototype.jsもそれらと同類なのだろうと思っていました。
で、実際にprototype.jsを読んでみたら、なんと単純、それでいて、センスの塊!難しいことなんてひとっつもやってないのに、魔法のように、いろんな問題を解決していってます。
よく、「オープンソースを読むのが、一番勉強になる」なんて言いますが、結構難しいですよね。それでつまづいてしまった人や、初めてオープンソースを読む人には、prototype.jsは、お奨めです。
$()
そもそも、$()をみて、私はJSの文法自体を変えてしまっているのだと勘違いしていました。
タダの関数なんですね。
funtion $(id){
return document.getElementById(id);
}
var domElement = $('id');
と、
funtion getDomElement(id){
return document.getElementById(id);
}
var domElement = getDomElement('id');
は、同じこと。Java文法に慣れてる、センスのない私は、後者を選んでしまいます。
「なーんだ、そんなのくだらない」と思うのか、「うわ、スゲー」と思うのかは、人それぞれだとは思いますが、ここで関数名として、$を採用するかしないかは、大きな差、なのではないかと思います。
そういえば、シェルコマンドで、"["ってのがあります。
if [ -e "~/.lock" ]; then #.lockが存在していれば・・・
・・・
fi
この"["は、文法ではなく、コマンドです。"-e"とか、"]"は、"["コマンドのパラメータなんですね(ややこしい?)。
記号だとみせかけたコマンド・関数って、なんでこんなこと考えつくんだろうなー・・・と感心することしきりです。
Object.extend
prototype.jsの冒頭で、継承(extend)の実現があります。中身は馬鹿みたいに簡単。
Object.extend(child, parent);
と書けば、parentの全プロパティをchildにコピーするだけ。
継承とは何か?みたいな教科書がたくさんありますが、継承ってこれだよ。と、このソースを見せたいw。
prototype
そして、JavaScriptの文法としては、Object.prototypeで、適当にクラスメソッドを追加できることになっているので、
Array.prototype.each=function(iterator){}
を定義してやれば、冒頭のRubyのようなイテレーターが書けるようになるわけです。なんとも単純な話ですね!
Try
Try.theseには、いわゆる「スクリプト言語」の個性が、端的に凝縮されてると思いました。
可変長パラメータの取得の仕方や、無名関数の実行の仕方など。無名関数(Lambda式)ってなんなの?と思っている方は、このコードを読めば一発で理解できると思います。
//prototype.jsで定義されてる。
var Try = {
these: function() {
var returnValue;
for (var i = 0; i < arguments.length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}
return returnValue;
}
}
//var Ajaxの一部。
//非同期通信オブジェクトを取得している。
//取得できるオブジェクトはブラウザ毎に異なるため、
//取得に成功したものだけを返す。
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
Tryとか、Ajaxとか、Javaユーザーからすればクラスに見えるものも、実はただの変数。「関数が値」のハッシュ(連想配列)だったりします。前述のObject.extendも、ただ単に、ハッシュの参照をコピーしているだけなわけです。
これをみても、クラスとは何だ?と言われれば、ただのハッシュだ。という言い方もできるかもしれません。
このあたりの、スクリプト脳に慣れてしまえば、あとは簡単。結構スラスラと読めてしまいます。Javaを使い続けて凝り固まったアタマには、いい刺激をいただきました。もうちょっと読み進めてみたいとは思いますが、また別の機会に。

