宇宙野武士は元気にしているか

2008-05-24

[]constructorとprototype.constructorがわからなくなった

constructor(プロパティ)とprototype.constructor(プロパティ)は

別物だと思っていたけど、やっぱり同じ物だとおもいつつもやっぱり違うのか?と

よくわからなくなってきた。(特に継承とかしようとした場合に)

ので少し調べてみた。

(ちなみにSpiderMonkeyをつかって試している)

constructorプロパティとは

サイ本によると、

オブジェクト初期化で使用されたコンストラクタ関数を参照する。

とある。

var a = new Array();
a.constructor == Array;//>trueになる

確かに、Arrayオブジェクトでnewした変数aのconstructorプロパティ

Arrayになっているようだ。

じゃあ、Arrayのconstructorプロパティってなんだろ?

これで気になったのは、newしてないArrayオブジェクトのconstructor

プロパティはなんだろう?

それはFunctionオブジェクト。はて?

自作したオブジェクトで考えるとわかりやすいかも

自作で用意したHogeオブジェクト

function Hoge(x){
  this.x = x;
}

と定義する。

HogeのconstructorプロパティもFunctionだ。

これは、書き換えると

var Hoge = new Function("x", "this.x = x");

とも書ける。Arrayオブジェクトのように組み込みオブジェクトは見えないけど

Functionオブジェクトをnewして作られているんだなと考えるとイメージしやすい。

(ただしこの2つは微妙に違いがあるようなのであくまでも考え方です)

続いてprototype.constructorプロパティ

その前にprototypeプロパティとは

関数が定義されたときに自動的に生成される。初期値はconstructor

プロパティのみのオブジェクトのこと。

prototype.constructorプロパティとは

コンストラクタ関数自信を参照する。

ということで、みてみよう。先ほどのHogeオブジェクトでみてみる

Hoge.prototype.constructor == Hoge; //>true

確かにコンストラクタ関数と同じだ。

さあ、こんがらがっていこうか!

ここで問題。

Hogeオブジェクトをnewしてできた変数hoge

prototype.constructorプロパティはなにか?

なんかHogeっぽくも思える。

でも、

var hoge = new Hoge("hoge");
hoge.prototype.constructor == Hoge;

の結果はhoge.prototypeにそんなプロパティはないよって怒られる。

正解はエラーになる。ですな。

さらに、prototypeプロパティはundefinedになってる。

なーんでか?

先ほどのprototypeプロパティとはで書いた定義をよく見ると、

関数が定義されたときに自動的に生成される。

とある。

変数hoge関数として定義したわけでないからprototypeプロパティはないわけだ。

見えてきた?2つのconstructorプロパティの関係

ということで、最初のconstructorプロパティ

prototype.constructorプロパティは別か同じかという疑問の答えは

別物とあっさりでてしまった。

そして、不思議なことに、

Hogeオブジェクトとそのオブジェクトから作られたhogeを比較すると、

hoge.constructor == Hoge.prototype.constructor; //>true

と同じものになる。さらに

Hoge.constructor == Function.prototype.constructor; //>true

も同じになる。

newされて生成された変数インスタンス)のconstructorプロパティ

コンストラクタ関数prototype.constructorプロパティが設定されてるって

考えられるんだ。

なんだか、脈々と受け継がれている関係がみえてきたような。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。