JavaScript 入門

ホーム > JavaScript の基本 > プロトタイプ

プロトタイプ

ここでは JavaScript のプロトタイプ (prototype)というものについて説明します。

プロトタイプは JavaScript のオブジェクト指向プログラミングを語る上では非常に重要なものです。

プロトタイプとは?

コンストラクタ の説明でも記載しましたが、 コンストラクタを定義すると、コンストラクタ毎に関連付けされた "プロトタイプオブジェクト" というのが暗黙的に作成されます。 そして同じコンストラクタから生成されたオブジェクトは、プロトタイプオブジェクトを共有します。

このオブジェクトは prototype プロパティからアクセス可能です。

具体的に確認しましょう。次のようにコンストラクタ Person を用意しておき、変数 p1, p2 に対してそれぞれ new Person します。

function Person(n){
	this.name = n;
}

var p1 = new Person('Ichiro');
var p2 = new Person('Hanako');

if( p1 === p2 ) {
	//これは false
}

if( p1.prototype === p2.prototype ) {
	//これは true
}

そして、p1 === p2p1.prototype === p2.prototype を確認すると、前者は false (つまり異なるオブジェクト) ですが、 後者は true (つまり同じ prototype オブジェクト) であることがわかります。

また prototype オブジェクトのメソッドやプロパティは、オブジェクトから ".property" 抜きでアクセス可能です。 このため、プロトタイプオブジェクトに対して、関数やプロパティを定義すれば、作成されたオブジェクトは同じ関数やプロパティを持つものとして利用可能になります。

また、prototype オブジェクトを別のオブジェクトに差し替えることによって、差し替えたオブジェクトの prototype オブジェクトともリンクさせることができます。

さっそく試してみましょう。

次のコードでは Person コンストラクタを用意して、 そのプロトタイプオブジェクトに city プロパティと moveTo 関数をセットします。

moveTo 関数ではプロトタイプオブジェクトの city プロパティを書き換えています。

function Person(n){
  this.name = n;
}

Person.prototype.city = 'Tokyo';
Person.prototype.moveTo = function(c){  
  document.write(this.name + ': Moving to... ' + c + '<br>');
  Person.prototype.city = c;
}

var p1 = new Person('Ichiro');

document.write( p1.name + '<br>');
document.write( p1.city + '<br>');


var p2 = new Person('Hanako');

document.write( p2.name + '<br>');
document.write( p2.city + '<br>');


p2.moveTo('Los Angeles');

document.write( p2.city + '<br>');
document.write( p1.city + '<br>');


p1.age = 20;

document.write( p1.age + '<br>');
document.write( p2.age + '<br>');

この実行結果は次のようになりました。

Ichiro
Tokyo ← Ichiro の city
Hanako
Tokyo ← Hanako の city
Hanako: Moving to... Los Angeles ← Hanako の city を LA に変更
Los Angeles 
Los Angeles ← Ichiro の city も LA に変わった!
20 ← Hanako の age を 20 いセットしたが・・・
undefined ← Ichiro の age は未定義

このコードの意味を順に見て行きます。

変数 p1 に Person オブジェクトを設定。引数として 'Ichiro' を渡しています。また、 p2 には 'Hanako' という文字列を渡して作成した Person オブジェクトを設定。 この文字列は this.name プロパティにセットされます。

そこで name プロパティと city プロパティの値を見ると、p1 と p2 では name はそれぞれ、 コンストラクタに渡した値になっていますが、city は 'Los Angeles' となります。

これは Person コンストラクタに対するプロトタイプオブジェクトの city プロパティがみえていることになります。

p2 オブジェクトの moveTo メソッドを呼び出すことで、city の値を 'Los Angeles' に設定します。 ここで p1, p2 の city プロパティを見ると、どちらも 'Los Angels' になります。

これはすなわち、p1, p2 で city プロパティが共有されていることを意味します。

念のため、共有されないプロパティをみてみましょう。

p1 に対して age プロパティをセットします。これは共有されないオブジェクト (this) に、 セットされていますから、p2 の age プロパティを見ても未定義となることがわかります。

ホーム > JavaScript の基本 > プロトタイプ