「base.js」とは、プロトタイプベースのオブジェクト指向プログラミングを支援するためのJavaScriptライブラリです。SIEを軽量化するために作られた、自身も軽量なライブラリ( gzip圧縮で621バイト)です。オープンソースで、MITライセンスを採用しています。
SIEのパッケージをダウンロードしてください。パッケージを解凍した後、その中にある tool/funcproto/ ディレクトリに、base.jsというファイルがあります。
ソースコードは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」としておきましょう。これで、準備はすみました。
続けて、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という文書がポップアップで表示されて、これで成功です。
base.jsでは、いろいろな関数やメソッドを用意していますので、それを解説していきます。
オブジェクトを生成、参照するために、呼び出す関数です。引数には、文字列を使って、オブジェクトの名前を付けます。 返り値は、生成したオブジェクトとなります。
base("$hoge");作ったオブジェクトを参照したい時は、同じ名前で呼び出すことができます。
( base("$hoge") === base("$hoge") ); // trueこのbase関数によって作られたオブジェクトには、あらかじめ、いくつかメソッドが用意されています。これらのメソッドを使うことで、オブジェクト指向プログラミングを実現します。
オブジェクトを合成したい時に使います。強力なメソッドです。引数には、合成しておきたいオブジェクトを入れます。 例えば、$hogeオブジェクトにhogehogeメソッドを指定してみましょう。
base("$hoge").mix( { hogehoge: function(){} } );指定したhogehogeメソッドの呼び出しは以下のとおりです。
base("$hoge").hogehoge();このサンプルコードでは、$hogeオブジェクトに、hogehogeメソッドを定義しています。 もちろん、オブジェクトリテラル以外でも、別のオブジェクトでも構いません。
base("$$hoge").mix( base("$hoge") );また、引数には関数を使うことができます。
base("$hoge").mix( function() {} );thisには$hogeオブジェクトが入っています。ですので、次のような書き方ができます。
base("$hoge").mix( function() { this.hogehoge = function() {}; } );このコードは、$hogeオブジェクトに、hogehogeメソッドを定義するわけです。 このmixメソッドの返り値は、レシーバのオブジェクトですので、メソッドチェーンを使うことができます。
base("$hoge").mix({}) .mix({});
オブジェクトの継承をするために、新しいオブジェクトを作るメソッドです。引数には、文字列を使って、新しく作るオブジェクトの名前をいれておきます。
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このような機能を、名前空間と呼びます。
メソッドの合成ができるメソッドです。おもに、非同期処理や初期化などで使います。 第一引数には、メソッド名が、第二引数には、関数が入ります。
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;これを使えば、初期化のみならず、非同期処理にも応用できるでしょう。
callメソッドといっしょに使います。mixメソッドと書き方は同じですが、効果は異なります。 このメソッドとcallメソッドを使うことで、コンストラクタで力を発揮します。 例えば、簡単な足し算の例を見てみましょう。
base("$hoge").of( { p: base("$h"), pp: base("$hh"), call: function() { return this.p+this.pp; } } ); base("$h").call = function() { return 12; }; base("$hh").call = function() { return 15; } base("$hoge").call(); // 27を返すこのように足すことができましたが、具体的には何をやっているのでしょうか。詳しい解説はcallメソッドでやりたいと思います。
of メソッドでは、プロパティにオブジェクトを指定していました。 上の例でいうと、$h オブジェクトと$hh オブジェクトが、それぞれ、pプロパティとppプロパティに指定されています。しかし、実際にはオブジェクトが入っていません。では、$h がどこに入っているかと言うと、$hoge オブジェクトの_pプロパティに入っています。
base("$hoge")._p === base("$h"); // trueこのとき、of メソッドを使った$hoge オブジェクトに対して、callメソッドを呼び出します。すると、$h オブジェクトのcallメソッドが呼び出されて、返り値をp プロパティに入力するのです。
説明より、例を見てもらった方が理解しやすいでしょう。
base("$hoge").p; // このときはundefined。_pプロパティに$h オブジェクトが入る base("$hoge").call(); // 27を返す base("$hoge").p === base("$h").call(): // どちらも12なので、trueこうして、callメソッドを使うことで、オブジェクトそのものが一つの関数としてふるまうことができます。
オブジェクト指向プログラミングとして、いろいろなことができるのもbase.jsの特長です。
まずは、$hogeオブジェクトと、それを継承した$childオブジェクトを作っておいて、hogehogeメソッドを定義します。そのメソッドのオーバライドをしてみましょう。この方法は、カンタンです。
base("$hoge").mix( { hogehoge: function() { return "ow"; } } ) .up("$child").mix( { hogehoge: function() { return this.$hoge.hogehoge.call(this); } } ); base("$hoge").$child.hogehoge(); // "ow"$childのメソッドから、親の$hogeオブジェクトを呼び出すには、メソッド内で、this.$hogeプロパティをつければいいのです。こうすれば、$hogeオブジェクトを指定したことになります。
クロージャの仕組みと、mixメソッドを組み合わせると、カプセル化もできます。
base("$hoge").mix( function() { var my = "es"; this.hogehoge = function() { return my; } } );この変数myがプライベートな変数です。クロージャによって、外部から保護されています。
[PageInfo]
LastUpdate: 2018-01-13 17:36:15, ModifiedBy: dhrname
[License]
Creative Commons 4.0 Attribution
[Permissions]
view:all, edit:all, delete/config:members