- 2008-02-26 (火)
- JavaScript
今度はprototypeにメソッドを追加して、以下の結果が出るプログラムを作る。
var tanaka = new generateAgeCounter('1934-06-15');
console.log(tanaka.getDate('1968-07-14')); // 34
console.log(tanaka.getDate('1958-07-15')); // 24
var yoshida = new generateAgeCounter('1974-06-15');
console.log(yoshida.getDate('2005-07-14')); // 31
console.log(yoshida.getDate('2066-07-15')); // 92
はじめは前回のものをこのように書いた。
generateAgeCounter.prototype.parseDate = function (date_text) {
if (String(date_text).match(/^(?:(\d{4})-|)(\d{2})-(\d{2})$/)) {
var year = RegExp.$1, month = RegExp.$2, day = RegExp.$3;
return year + month + day;
} else {
return false;
}
}
function generateAgeCounter(d) {
var birth_date = this.parseDate(d);
this.getDate = function(diff_d) {
return parseInt((this.parseDate(diff_d) - birth_date) / 10000);
}
}
これでも望みの結果が出たが、ここでgetDateはすべての
オブジェクトで共有されるはずのメソッドなのでさらにprototypeに足してみる。
//コンストラクタ
function generateAgeCounter(d) {
var birth_date = this.parseDate(d);
}generateAgeCounter.prototype.parseDate = function (date_text) {
if (String(date_text).match(/^(?:(\d{4})-|)(\d{2})-(\d{2})$/)) {
var year = RegExp.$1, month = RegExp.$2, day = RegExp.$3;
return year + month + day;
} else {
return false;
}
}generateAgeCounter.prototype.getDate = function(diff_d) {
return parseInt((this.parseDate(diff_d) - birth_date) / 10000);
}var tanaka = new generateAgeCounter('1934-06-15');
console.log(tanaka.getDate('1968-07-14')); // 34
console.log(tanaka.getDate('1958-07-15')); // 24var yoshida = new generateAgeCounter('1974-06-15');
console.log(yoshida.getDate('2005-07-14')); // 31
console.log(yoshida.getDate('2066-07-15')); // 92
でちゃんと動いた(けどいいのかな?)
以下を読んで、
クロージャの良さと、オブジェクトは使い分けるべきのようだ。
カウンタは、スコープがあり状態を保持する必要があるため、関数は向いてないな。
簡単なカウンタだったらクロージャで充分で、リッチなカウンタだったらオブジェクトが便利だな、と考えられます。コントロールに色を付け、徐々に色が薄くなっていくような処理だったらどうでしょうか?
必要な処理は、色を薄くする処理の一つだけなのでオブジェクトは使う必要はなさそうです。
クライアントにストップなどの処理を一つ渡す必要があるならクロージャ、そうではなくスタートだけなら関数で充分だと思います。
クロージャで良いところへオブジェクトを持ってくるのは大げさです。
複雑な状態を持つものを関数やクロージャで書くのも無理があります。
それぞれのメリットを生かし、適材適所でミックスして使いプログラミングをするのが良いと思っています。
もう少し体感覚でこのあたりを覚えたい。
引き続き勉強しよう。
以下、JavaScript 第5版 P,151〜P,163あたりの備忘録としてのメモ
オブジェクト指向的なコードであれば、関数にオブジェクトを引数として渡す のではなく、オブジェクトに対してメソッドを呼び出すようにする。
var a = r.area();
コンストラクタは、オブジェクトの「クラス」を定義し、widthやheightプロパティを
初期化します。コンストラクタで初期化されたオブジェクトは、コンストラクタに
関連付けられたプロトタイプオブジェクトからまったく同じプロパティを継承します。
このような理由により、プロトタイプオブジェクトはメソッドや定数プロパティを
定義するのに理想的なのです。プロパティが継承されたものかどうかを区別するためには、Object.hasOwnProperty()
メソッドを使う。たとえば、オブジェクトoのプロパティpを読み出すときにJavaScriptは最初に
オブジェクトoにプロパティpがあるかどうかをチェック。もしなかった場合、
オブジェクトoのプロトタイプオブジェクトにプロパティpがあるかどうかを
チェックします。プロトタイププロパティは、あるクラスのすべてのオブジェクトで共有されるので
そのクラスのすべてのオブジェクトに対して同一のプロパティを定義する場合に
限って使用するのが一般的です。たとえばメソッドの定義や数学定数など。
- Newer: John Butler Trio - Ocean
- Older: 世界のナベアツ問題 on Javascript