サラリーマン技術者の調査レポート

日々の業務で気付いた当たり障りのない技術的なあれこれを綴ります。

constructorとprototype

JavaScriptのconstructorとprototypeについての備忘録です。 サンプルコードはChrome(Chromium)のJavaScriptコンソールで実行したものです。

コンストラクタ

JavaScriptコンストラクタは単なる関数です。 ただ、new演算子を付けて呼び出されることを想定していることと、慣例として関数名の先頭を大文字にしているところが普通の関数と異なります。 例としてPersonというコンストラクタを定義してみます。

function Person() {};

コンストラクタにnew演算子を付けて呼び出すと新しいオブジェクトが生成されます。

var person = new Person();

プロトタイプ

コンストラクタにはprototypeというプロパティが存在します。

console.log(Person.prototype);

これを実行すると

Person {}

と出力されます。が、prototypeは中身が空っぽの単なるオブジェクトです。試しに

typeof Person.prototype;

を実行すると

"object"

と出力されます。

Person.prototype instanceof Person;

これはfalseになります。

このprototypeはコンストラクタで生成した新しいオブジェクトのベースになります。 「ベース」ってなんだ?というのは今回は省略します。

再びコンストラクタ

Personコンストラクタから生成したpersonオブジェクトにはconstructorというプロパティが存在します。

console.log(person.constructor);

を実行すると

function Person() {}

と出力されるので、Personコンストラクタを指していることがわかります。 つまり、オブジェクトはそれを生成したコンストラクタをプロパティとして保持していることになります。

おまけ

コンストラクタもconstructorプロパティを保持しています。このconstructorプロパティはFunctionオブジェクトのコンストラクタになります。

Person.constructor

を実行すると

function Function() { [native code] }

となります。これはつまりコンストラクタが関数であることを示しています。

また、オブジェクトにprototypeプロパティはありません。

person.prototype

を実行すると

undefined

となります。プロトタイプは、そのオブジェクトを生成したコンストラクタが保持しているものであって、オブジェクト自身はprototypeを保持しません(が、ベースになります)。 もしpersonオブジェクトからそのプロトタイプを辿りたい場合には

person.constructor.prototype;

とする必要があります。

また、プロトタイプにもconstructorプロパティがありますが、

console.log(Person.prototype.constructor);

を実行すると

function Person() {}

と出力されます。なぜ?って感じですがとりあえずスルーします。

まとめ