== base.jsとは 「base.js」とは、インスタンスベースのオブジェクト指向プログラミングを支援するためのJavaScriptライブラリです。SIEを軽量化するために作られた、自身も軽量なライブラリ( gzip圧縮で621バイト)です。オープンソースで、MITライセンスを採用しています。 == 特徴 1. オープンソース 2. インスタンスベースのオブジェクト指向プログラミングの支援 3. JavaScriptで記述 4. 軽量なライブラリ == ダウンロード [http://sourceforge.jp/projects/sie/releases/ SIEのパッケージ]をダウンロードしてください。パッケージを解凍した後、その中にある tool/funcproto/ ディレクトリに、base.jsというファイルがあります。 == Git ソースコードはGitで取得できます。マスターブランチのレポジトリ、http://sourceforge.jp/projects/sie/scm/git/sie/tree/master/tool/funcproto/ をご覧下さい == サンプルコード {{{ base("$hoge").mix( { init: function () {} } ).up("$hogehoge"); base("$hoge").init(); }}} 別の書き方もできます。 {{{ base("$hoge").up("$hogehoge"); base("$hoge").mix( { init: function () {} } ); }}} できるだけ、簡単に書けるように、また、さまざまな書き方ができるようにすることで、オブジェクト指向プログラミングを軽量化できるのです。 == 初心者のための導入手順 ここでは、ブラウザ上で使いたいときに、JavaScript初心者のために、base.jsを導入するためのやり方を述べていきます。まず、SIEをダウンロードをして、tar.gz形式のパッケージを解凍します。解凍できましたら、tool/funcproto/ディレクトリにある、「base.js」という名前のファイルを、自分の好きなディレクトリにコピーしてください。コピー先のディレクトリを仮に「doc」としておきましょう。これで、準備はすみました。 === ここまでの確認 1. SIEをダウンロードして、解凍 2. 「base.js」というファイルがあるので探す 3. 2のファイルを好きなディレクトリにコピー 続けて、HTMLファイルを用意して、docディレクトリにいれます。できましたら、そのHTML文書に、次の一文を追加してください。(処理を早くするため、できれば、body要素の終了タグの前がいいでしょう) {{{ <script src='base.js' type='text/javascript'></script> }}} これが、base.jsを読み込むためのscriptタグとなります。 さらに、今度はサンプル用のJavaScriptファイルを用意します。ここでは仮に「sample.js」としておきます。これもHTMLファイルと同じように、docディレクトリにいれておきましょう。 先ほどのHTMLファイルを文書エディターで開いて、<script>タグを書いておいた場所に、次の一文を追加します。 {{{ <script src='sample.js' type='text/javascript'></script> }}} さて、sample.jsに次のようなコードを書いてみましょう。 {{{ base("$hoge").mix( { init: function () { alert("Hello! World"); } } ); base("$hoge").init(); }}} 後はブラウザを起動して、作ったHTMLファイルを読み込めば、Hello! Worldという文書がポップアップで表示されて、これで成功です。 === ここまでの確認 1. HTML文書を用意 2. 1で用意した文書に、base.jsを読み込むための、scriptタグを書き込み追加 3. 別に、サンプル用のJavaScriptファイルを用意して、同様にscriptタグを追加 4. 1のHTML文書をブラウザで読み込めばOK == API base.jsでは、いろいろな関数やメソッドを用意していますので、それを解説していきます。 === base 関数 オブジェクトを生成、参照するために、呼び出す関数です。引数には、文字列を使って、オブジェクトの名前を付けます。 返り値は、生成したオブジェクトとなります。 {{{ base("$hoge"); }}} 作ったオブジェクトを参照したい時は、同じ名前で呼び出すことができます。 {{{ ( base("$hoge") === base("$hoge") ); // true }}} このbase関数によって作られたオブジェクトには、あらかじめ、いくつかメソッドが用意されています。これらのメソッドを使うことで、オブジェクト指向プログラミングを実現します。 === mix メソッド オブジェクトを合成したい時に使います。強力なメソッドです。引数には、合成しておきたいオブジェクトを入れます。 例えば、$hogeオブジェクトにhogehogeメソッドを指定してみましょう。 {{{ base("$hoge").mix( { hogehoge: function(){} } ); }}} 指定したhogehogeメソッドの呼び出しは以下のとおりです。 {{{ base("$hoge").hogehoge(); }}} このサンプルコードでは、$hogeオブジェクトに、hogehogeメソッドを定義しています。 もちろん、オブジェクトリテラル以外でも、別のオブジェクトでも構いません。 {{{ base("$$hoge").mix( base("$hoge") ); }}} また、引数には関数を使うことができます。 {{{ base("$hoge").mix( function() {} ); }}} このmixメソッドの返り値は、レシーバのオブジェクトですので、メソッドチェーンを使うことができます。 {{{ base("$hoge").mix({}) .mix({}); }}} === up メソッド オブジェクトの継承をするために、新しいオブジェクトを作るメソッドです。引数には、文字列を使って、新しく作るオブジェクトの名前をいれておきます。 {{{ base("$parent").up("$child"); }}} 返り値は新しく作ったオブジェクトです。この新規オブジェクトは、レシーバのオブジェクトを継承できます。 継承すれば、親のメソッドやプロパティを使えるようになります。 {{{ base("$parent").mix( { hoge: function() { return 12; } } ); base("$parent").up("$child").hoge(); //12 }}} $childオブジェクトは$parentオブジェクトのメソッドが使えるので、$parentオブジェクトを継承しているわけです。 また、次のように、一度作ったオブジェクトは、親オブジェクトのプロパティで参照します。 {{{ base("$parent").$child; base("$parent").$child.hoge(); //12 }}} このような機能を、名前空間と呼びます。 === on メソッド メソッドの合成ができるメソッドです。おもに、非同期処理や初期化などで使います。 第一引数には、メソッド名が、第二引数には、関数が入ります。 {{{ base("$hoge").mix( { hogehoge: function(){} } ) .on( "hogehoge", function() {}); base("$hoge").hogehoge(); //hogehogeメソッドを呼び出す }}} 関数は登録された順に実行されますので、ご注意下さい。なお、hogehogeメソッドが始めからない場合、最初に指定したonメソッドの関数が、メソッドとして登録されます。 次のコードでは、xプロパティを1ずつ足していくhogehogeメソッドを作っています。 {{{ base("$hoge").on( "hogehoge", function() { this.x = 0; this.x++; }) .on( "hogehoge" , function() { this.x++; }); base("$hoge").hogehoge(); base("$hoge").x; // 2; }}} 第二引数で指定した関数のthisに注目してください。 このthisは、束縛されていませんので、レシーバである$hogeオブジェクト ( つまり、 base("$hoge") の返り値 )を表しているのです。 また、メソッドの引数を、関数の引数に引き継ぐことができますので、初期化も可能です。 {{{ base("$hoge").on( "initialize", function(obj) { this.px = obj.x; }) .on( "initialize" , function(obj) { this.py = obj.y; }); base("$hoge").initialize( { x: 2, y: 3 } ); base("$hoge").px; // 2; base("$hoge").py; // 3; }}} このメソッドの利点は、upメソッドでも合成を引き継ぐことです。 試しに、さきほどの初期化コードを、upメソッドを使って、$childオブジェクトにも使えるようにしましょう。 {{{ base("$hoge").on( "initialize", function(obj) { this.px = obj.x; }) .up("$child") .on( "initialize" , function(obj) { this.py = obj.y; }); /*$childオブジェクトでinitializeメソッドを実行*/ base("$hoge").$child.initialize( { x: 2, y: 3 } ); base("$hoge").$child.px; // 2; base("$hoge").$child.py; // 3; }}} これを使えば、初期化のみならず、非同期処理にも応用できるでしょう。