JavaScriptのオブジェクトの生成、特にコンストラクタに次のデザインパターンを適用します。
最初の関数
指定された文字を指定された回数繰り返します。
var repeat = function (string, number){ var i, result = ""; for(i = 0; i < number; i++ ) { result += string; } return result; } repeat("abc", 3);
メリット | 書くのが簡単 |
デメリット | (規模が大きいと)何に使う処理か分からなくなる |
オブジェクトリテラル
引数をオブジェクトで受け取り、一つの塊にします。
var repeat = function (param){ var i, result = ""; for(i = 0; i < param.number; i++ ) { result += param.string; } return result; } repeat ({ string: "abc", number: 3 });
メリット | データのまとまりを作れる |
デメリット | オブジェクトに設定すべきプロパティが分からない |
例えば、値の組み合わせをひとまとまりのデータとして扱えます。
var data1 = { string: "abc", number: 3 }, data2 = { string: "xyz", number: 5 }
オブジェクトにどのような値を設定すれば良いか、処理の中身を見ないとわかりません。
- 値の名前
- 値の型(文字列、数値、日付)
- 値の意味
基本のコンストラクタパターン
クラスベースのオブジェクト指向のように、データと処理の定義をまとめます。
- 処理をメソッドにする
- データはコンストラクタで指定する
var Repeater = function(str, num){ var string = str, number = num; this.repeat = function (){ var i, result = ""; for(i = 0; i < number; i++ ) { result += string; } return result; }; }; new Repeater("abc", 3).repeat();
メリット | データと処理の定義を一か所に書ける |
デメリット | 関数定義が共有されない |
JavaScript ではクラス用の記法が無いため、メソッドでも new される度に新しい関数オブジェクトを生成します。
プロトタイプを使ったコンストラクタパターン
メソッドをprototypeに定義します。repaet関数の定義をコンストラクタの外で行うのでstringとnumberをRepeterのプロパティにします。
var Repeater = function(str, num){ this.string = str; this.number = num; }; Repeater.prototype.repeat = function (){ var i, result = ""; for(i = 0; i < this.number; i++ ) { result += this.string; } return result; }; new Repeater("abc", 3).repeat();
メリット | メモリを節約 |
デメリット | クラス定義が2文に分かれる |
JavaScript では prototype に設定されたプロパティを new 演算子で生成されたすべてのインスタンスで共有します。
モジュールパターン
即時関数(Immediately-invoked function expression)を使ってクラス定義をまとめます。
var Repeater = (function (){ var constructor = function(str, num){ this.string = str; this.number = num; }; constructor.prototype.repeat = function (){ var i, result = ""; for(i = 0; i < this.number; i++ ) { result += this.string; } return result; }; return constructor; })(); new Repeater("abc", 3).repeat();
メリット | クラス定義がまとまる |
デメリット | 複雑すぎる |
参考図書
2.1 コンストラクタパターン を参考にしました。