吉本集の個人ブログ
Web制作の技術について書いています。たまに日記も書きます。

prototypeについて

2014年10月8日 / category : javascript, lab

現在、TypeScriptを習得中です。gruntでコンパイルしているのですが、黒い画面が・・・苦手です。
ただ、言語を覚えるのは、やはり面白い。
TypeScriptはクラスベースの言語なので、自分的にはとても入りやすい。
ActionScriptをやっていてよかったなと、改めて思います。

TypeScriptを勉強していると、JavaScriptの勉強にもなる。
そこで、JavaScriptの基礎的なところを改めてしっかりと復習しようと思います。

JavaScriptはクラスという概念がありません。
しかし、TypeScriptはクラスベースの言語なので、コンパイルするとどういうコードになるのか、ここをしっかりと理解しなければいけません。
そこでまず、prototypeを改めて復習します。

以前の記事でprototypeについて少し触れていますが、

■クラス定義(プロトタイプ)について
http://tsudoi.org/weblog/?p=1505

■クラス(プロトタイプ)の継承について
http://tsudoi.org/weblog/?p=1509

もう少ししっかりとした記事を書きます。

まず、prototypeとは何か。

prototypeとは、関数が持っているプロパティです。

JavaScript
var test = function(){};
console.log( test.prototype );

これを実行すると、コンソールに”Object”が出力されます。
test関数を生成すると、自動的にprototypeプロパティが生成されたことがわかります。

では、このprototypeプロパティとは、何か。
JavaScriptは、プロトタイプ(原型)を作成し、インスタンスを生成するプロトタイプベースの言語です。
次のコードを見てみます。

JavaScript
var A = function(){};
A.prototype.hello = function(){
	console.log('Hello!');
};

var a = new A();
a.hello();

“Hello!”が出力されます。
これがどういう作りなっているのか。

A関数を定義し、prototypeプロパティに、helloメソッドを定義しました。
変数aに、newでA関数を生成し代入します。この変数aがA関数のインスタンスとなります。
このインスタンスがhelloメソッドを実行しています。
変数aには、helloメソッドを定義していないのに、なぜ実行できるのか。

これがprototypeです。

インスタンスを生成することで、そのインスタンスは親(プロトタイプ)のプロパティを使用することができます。
そのプロパティを定義するのが、prototypeです。

また、prototypeを使用することで、継承ができます。
例えば、次のコードを見てみます。

JavaScript
var A = function(){};
A.prototype.hello = function(){
	console.log('Hello!');
};

var B = function(){};
B.prototype = new A();
B.prototype.goodevening = function(){
	console.log('Good evening!');
};

var b = new B();
b.hello();

“Hello!”が出力されます。
B関数が、prototypeでA関数を継承しています。

B.prototype = new A();

このことで、A関数のprototypeで定義したhelloメソッドをB関数のインスタンスは使用することができます。
これはプロトタイプチェーンと呼ばれる仕組みです。

B関数のインスタンスである変数bが、helloメソッドを実行すると、B関数のprototypeにhelloメソッドがあるかどうか探します。
無かった場合、継承されているA関数のprototypeを探しに行きます。
もし、A関数にも無かった場合は、Objectのprototypeを探しに行くことになります。