ちょっと便利なJavascriptオブジェクトの作り方
今回は、ちょっと便利なJavascriptオブジェクトの作り方をご紹介します。いわゆるモジュール・パターンと呼ばれている方法です。
はじめに
最近、HTML5への注目と共に、Javascriptを使用する機会が増えてきました。以下のように適用範 囲は多岐に渡っています。
- 通常のWebサイトでのユーザビリティ向上
- スマートフォン用Webサイト開発
- HTML5アプリによるクライアント・アプリ開発
- スマートフォンのハイブリッドアプリ開発
- Node.jsによるサーバサイド・プログラミング
このように、Javascriptが基幹となる仕組みが広がっています。クライアント側とサーバ側を同じ言語で作れることは、開発側にとってはとても有難いことです(学習コストの低減、人的リソース配分の柔軟性など)。もちろん、発注者やエンドユーアにとっても開発速度などの面で利益が生まれます。
Javascriptプログラミングを行う上で必須なのが、オブジェクトの作り方と活用です。従来、Javascriptといえばグローバル変数や関数を多用したプログラミングがなされていました。しかし今日では、Javascriptの使い方も洗練されてきており、オブジェクトを中心としたコードが一般的です。今後、Javascriptの開発をするには、オブジェクトの作り方・使い方について詳しく知る必要があります。
オブジェクト・リテラル
一番簡単な作り方は、いわゆるオブジェクト・リテラルです。ハッシュ形式でオブジェクトを定義する方法です。
var Person = {
name: 'kazushi',
age : 36,
init: function() {
// 何らかの処理
},
getName: function() {
return this.name;
},
getAge: function() {
return this.age;
},
// オブジェクト内部でしか使わないメソッド
doSomething: function() {
...
}
};
// 初期化を実行
Person.init();
この方法は非常に簡単な反面、全てのプロパティを外部から変更可能です。例えば、
Person.name = 'hoge hoge';
Person.age = 0;
などと、プロパティの値を保障できなくなります。また、doSomething()メソッドを外部から実行できてしまいます。複数人での開発などでは意図しないバグを発せさせかねません。また、影響範囲を明確に定義できない問題があります。そのため、保守性が下がってしまいます。さらに、再利用時には、どのメソッドを使用すべきか迷うことも多々あります。
モジュール・パターン
モジュール・パターンはオブジェクトリテラルより断然お勧めです。プライベートメンバや公開API設定などが容易だからです(リテラルなど通常の作り方の場合、Javascriptではスコープ定義が難しいんですね)。
このパターンでは即時関数を利用します。Javascriptでは即時関数と言って、無名関数をその場で実行する方法があります。例えば、次のように記述します。
(function() {
var i;
for (i=0; i<10; i++) {
// 何らかの処理
}
}());
Javascriptのコードが読み込まれた際に、実行されます。何が便利かというと、変数のスコープを限定し(Javascriptでは変数のスコープが関数単位)、影響範囲を狭めることができます。コードが長くなる際には必須の仕組みです 。
この即時関数を利用することで、オブジェクトのプライベートメンバ・メソッドや公開API設定を実施します。
var Person = (function(){
var _name = 'kazushi',
_age = 36;
function _init() {
// 何らかの処理
}
function _getName() {
return _name;
}
function _getAge() {
return _age;
}
function _doSomething() {
...
}
// 初期化を実行する
_init();
// 公開APIを返す
return {
getName: _getName,
getAge : _getAge
};
}());
ポイントは、即時関数内に変数と関数を定義し、最後に公開するものだけをオブジェクトで返している点です。こうすることで、_nameと_ageは外部から変更不可能となります。そして、Personオブジェクトの公開APIを設定でき、設計者の意図通りにこのオブジェクトを制限できます。ここでは_doSomething()関数を外部から実行することはできません。言葉を変えると、使う側は何を使えば良いかをすぐに理解できます。
また、公開APIの変更も簡単です(最後にreturnで返すオブジェクトを変更するだけですね)。
問題点としては、 読み込まれた時点でスクリプトが実行される点です。巨大なオブジェクトや複雑な計算を即時関数内に入れて、実行してしまうと時間が掛かります。同時にメモリも消費します。とはいえ、よほどおかしなことをしない限り、実際には大した問題にはなりません。
おわりに
即時関数を用いたJavascriptオブジェクトの作り方は、他にもいろいろとあります。多くのフレームワークでは、即時関数内でオブジェクトを定義し、必要なものだけをwindowオブジェクトのプロパティに追加する方法を使用しています。ちょっとした工夫で、Javascriptをより楽しく便利につかうことは十分可能です。ぜひ試してみて下さい。