• ベストアンサー

コンストラクタとプロトタイプについて

ネットで検索したりして調べているのですがいまいちわからなかった箇所が あるので質問させていただきます。 コンストラクタで設定するのとプロトタイプで設定する違いがいまいちわかりません。 例えば function Test { this.prop = hoge; } Test.prototype.prop1 = hogehoge; の場合 コンストラクタのほうが優先されてhogeがでるのはわかるのですが 下記の場合はプロタイプのほうが優先されてhogehogeと出てしまうのは どうしてでしょうか? <script language="javascript"> <!-- //コンストラクタ function Test(){alert("hoge"); } //prototypeでセット Test.prototype=alert("hogehoge"); //オブジェクト作成 var TEST = new Test(); window.onload=TEST; --> </script>

質問者が選んだベストアンサー

  • ベストアンサー
noname#30818
noname#30818
回答No.2

window.onload= function(){ function Test(){ this.prop = 'hoge'; }//関数 Test.prototype.prop1 = 'hogehoge';//これは何か良くわかりません。 alert(Test())//当然undefined function Test1(){ //関数(window.Test1) this.prop = 'hoge';//this(window)にプロパティを追加 return this //(window === this) } Test1().prop1 = 'hogehoge';//戻り値のwindowにプロパティを追加 var cc = '' for(var i in Test1()){ cc += 'Test1().' + i + '=' + Test1()[i] + '<br>' } document.body.innerHTML = cc function Test2(){ this.prop = 'hoge'; }//newで呼ばれているのでコンストラクタ関数 //どの JavaScript 関数もコンストラクタとして使用できます。new 演算子をコンストラクタ関数とともに使用することで新しいオブジェクトを作成します。 //http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Guide:Details_of_the_Object_Model#.E3.82.AF.E3.83.A9.E3.82.B9.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E.E3.81.A8.E3.83.97.E3.83.AD.E3.83.88.E3.82.BF.E3.82.A4.E3.83.97.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9Eより TEST2 = new Test2 //new 演算子に出くわしたので、"新しく汎用オブジェクトを生成"し、この新しいオブジェクトを this キーワードの値としてTest2コンストラクタ関数に渡します。 Test2.prototype.prop1 = 'hogehoge'; //内部的な __proto__ プロパティの値としてTest2.prototypeの値をセットします。 //http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Guide:Details_of_the_Object_Model#.E3.82.AF.E3.83.A9.E3.82.B9.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E.E3.81.A8.E3.83.97.E3.83.AD.E3.83.88.E3.82.BF.E3.82.A4.E3.83.97.E3.83.99.E3.83.BC.E3.82.B9.E8.A8.80.E8.AA.9E //”プロパティの継承”参照 var cc = '<br><br>' for(var i in TEST2){ cc += 'TEST2.' + i + '=' + TEST2[i] + '<br>' } document.body.innerHTML += cc function Test3(){ this.prop = 'hoge'; this.alert = function(){ alert(this.prop) }//メソッド?を追加 } TEST = new Test3 TEST.alert() function Test4(){ this.prop = 'hoge'; } TEST = new Test4 Test4.prototype.alert = function(){ alert(this.prop) }//メソッド?を追加 TEST.alert() //どちらも同じみたいですね。 //だた先ほどのページの”プロパティの追加”を読むと違いが解ると思います。 function Test5(){ this.prop = 'hoge'; } TEST5 = new Test5 Test5.prototype.prop = 'hoge*2' alert(TEST5.prop) //JavaScript がTEST5オブジェクト(Test5のインスタンス)のpropプロパティを探すと、JavaScript はそのプロパティに対するローカル値を発見します。そして Test5.prototypeへのチェーンの検索を停止します。 //ということでTEST5.propは'hoge*2'ではなく'hoge'で良いのだと思いますよ。 }

shoshosho
質問者

お礼

ご回答ありがとうございます。 いろいろ実験していただいて本当にありがとうございました。 試しにTest1を実行しようと思ったのですが 『function Test1(){ //関数(window.Test1)からdocument.body.innerHTML = cc までです。』 なぜか実行しても何も画面にでないのですがこれで正しいのでしょうか? たぶん私の手順が間違っているとは思うのですがいろいろ 試してもなぜか表示できませんでした。

shoshosho
質問者

補足

Test.prototype.prop1 = 'hogehoge' は Test.prototype.prop='hogehoge'の間違いでした。 すいませんでした。

その他の回答 (1)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

> //コンストラクタ > function Test(){alert("hoge");} このコンストラクタは"hoge"とアラートを表示する以外に何もしていません。 そのため、 > //オブジェクト作成 > var TEST = new Test(); でTESTには空(プロパティ無し)のオブジェクトが入ります。 (このとき、コンストラクタが実行されることでhogeが表示されます。) > //prototypeでセット > Test.prototype=alert("hogehoge"); ここではalertの戻り値をTest.prototypeにセットしています。 しかし、alertは戻り値を返しませんから、 Test.prototypeはundefinedになるでしょう。 (ここで、alert("hogehoge")は実行されることでhogehogeと表示されます。) # また、prototypeのプロパティではなく # prototype自体に代入することは普通はしないと思います。 > window.onload=TEST; TESTは空オブジェクトなので、onloadでは何も起こりません。 なにかアラートが出ているならこの手前の文がonload前に実行されたことによるものです。

shoshosho
質問者

お礼

ご回答ありがとうございます。 どうやらalertがでているのはonloadによるものではなかった みたいですね・・・。 試しにwindow.onload=TEST;を消してみて実行しましたが ダイアログが出てびっくりしましたが回答者様の解説の おかげでよくわかりました。 解説を見て疑問が沸いたのですが オブジェクト作成時にコンストラクタが実行されるのでしょうか? いまいちまだわかってなくてすいません・・;;

関連するQ&A