しまてく

学んだ技術を書きためるブログ

コンストラクタとプロトタイプ

はじめに

現在IEが実装しているJavaScript(バージョン 1.5)ではクラスという概念はありません。

ただし、関数やプロトタイププロパティを使ってクラスをシミュレートできます。

ということでクラス(便宜上)のまとめ

コンストラクタ

    • なんて事はない、普通の関数です。
var Circle = function( r ) {
//コンストラクタ
	//メンバ変数
	this.radius = r; //半径
	this.pi = 3.14;
	
	//メンバ関数
	this.area = function() { return this.radius * this.radius * this.pi; };
	this.length = function() { return this.radius * 2 * this.pi; };
}


上の例でも正しいことは正しいのですが、1つ問題があります。

この書き方をするとRectangleをnewしたときに常にthis.areaもメモリ上に

作成されてしまう、という問題です。



つまり、同じ関数を持ちたいだけなのにインスタンスの数だけメモリを無駄に消費しちゃう!

ってことです。


これを回避するためには↓

prototype プロパティを使う

var Circle = function( r ) {
//コンストラクタ
	//メンバ変数
	this.radius = r; //半径
}
Circle.prototype = {
	pi: 3.14,
	//メンバ関数
	area: function() { //面積
		return this.radius * this.radius * this.pi;
	},
	length: function() { //円周
		return this.radius * 2 * this.pi;
	}
};

こうすることでメモリが節約できるです。エコライフ☆パチパチ

prototype プロパティについて

すべての関数は定義時に自動的にprototypeプロパティが生成されます。

prototype プロパティとは、そのクラスのデフォルトの設定になります。(みたいなものだと理解してます)



prototype プロパティへのアクセスは

    • 1)インスタンスのプロパティを見る。
    • 2)なければprototype プロパティを見る。

という順番になります。

上のCircle クラスを使った例

var c1 = new Circle( 10 ); //半径10の円インスタンスを作成
var c2 = new Circle( 10 ); //半径10の円インスタンスを作成
alert( c1.area() ); //314が表示される(Circle.prototype の pi が参照される)
alert( c2.area() ); //314が表示される(Circle.prototype の pi が参照される)

c1.pi = 3; //c1のpi プロパティを追加する #ゆとり世代
alert( c1.area() ); //300が表示される(c1 の pi が参照される)
alert( c2.area() ); //314が表示される(Circle.prototype の pi が参照される)

Circle.prototype.pi = 4; //Circle.prototype の pi を変更する
alert( c1.area() ); //300が表示される(c1 の pi が参照される)
alert( c2.area() ); //400が表示される(Circle.prototype の pi が参照される)

こんな感じ?



C++に慣れた僕はJavaScriptOOPがなかなかしっくり来ないです><