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() {}
と出力されます。なぜ?って感じですがとりあえずスルーします。