• ベストアンサー

コンストラクタ?

FireFox2のエラーコンソールで以下のようなユーザ定義クラスを作成しています。 期待する動作は、documentに、 12 と出力されることです。 が、FireFoxのエラーコンソールには、 エラー: NewClass is not a constructor ソースファイル: file:///C:82%AF%E3%83%88%E3%83%83%E3%83%97/docs/temp.html 行: 20 と表示されています。おそらく、NewClass の コンストラクタの書き方が誤っているのではないかと思いますが、webで調べても正しいコンストラクタの書き方 というのが見つけ切れませんでした。期待動作を満たす為にはどのようにかけばよいでしょうか? <script type="text/javascript"> function NewClass(){    /*ここが誤っている?*/ // } NewClass = { ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} } ClassTest = new NewClass(); document.write( ClassTest.ClassValue1 ); document.write( ClassTest.ClassValue2 ); </script>

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

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

> (1)と(2)の違いは、プロパティやメソッドを定義したかしないかだと > 思うのですが、ということは、プロパティやメソッドを定義してしまうと、 > 関数オブジェクトにはならないということでしょうか? 違いは、 (1)はNewClassに関数オブジェクトを代入している、 (2)はNewClassに(関数でない)オブジェクトを代入している、 ところです。 NewClassに関数オブジェクトを代入するには、 以下のような方法がありますが、 いずれにしてもfunctionキーワード(かFunctionコンストラクタ)を使わなければ、 関数オブジェクトを作ることはできません。  function NewClass(){alert("test");}  NewClass = function(){alert("test");}; //名前無しの関数オブジェクトを作成して代入  NewClass = new Function('alert("test");'); //Functionコンストラクタを使用 (厳密には1番目と2,3番目は違うのかもしれませんが、試した限りではNewClassの挙動は同じでした。) それに対して(2)では、そもそも関数オブジェクトが作成されていません。 > NewClass = { >  ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} > } では、オブジェクト初期化子{ }により生成されたオブジェクト(≠関数オブジェクト)を NewClassに代入しています。 (2)の方法でだめなのは、そもそもオブジェクト初期化子が関数オブジェクトを返さないためで、 プロパティやメソッドの定義は関係ありません。 例えば、  function NewClass(){/* ... */}  NewClass.aaa="member_aaa"; のように関数オブジェクトNewClassにプロパティaaaを追加しても コンストラクタとして使うことはできると思います。 ただし、これでコンストラクタが返すオブジェクトに プロパティaaaが含まれるようになるわけではありません。 aaaはコンストラクタが返すオブジェクトのプロパティではなく、 あくまで関数オブジェクトNewClassのプロパティです。 (なので、関数オブジェクトにプロパティを追加する意味はあまり無いと思います。)

zuntata99
質問者

お礼

再三にわたるフォローありがとうございます。 骨子としては、functionキーワードを利用して定義したものでないと、 コンストラクタにはなりえない、ということですね。 下記のように書き直して、目的を達成できました。 表示するだけ、なら簡単だったのですが、意味を理解するところでつまづきました。このQ&Aは、後日もう一度理解を深めて読み返したいと思います。 function NewClass(){  this.ClassValue1 = 1;  this.ClassValue2 = 2;  this.ClassFunc = function(){alert("test");}; } ClassTest = new NewClass(); document.write( ClassTest.ClassValue1 ); document.write( ClassTest.ClassValue2 ); ClassTest.ClassFunc();

その他の回答 (6)

回答No.7

コンストラクタについての解説は他の方の回答を見てください。 > NewClass = { > ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} > } この書き方は、「JSON」で調べてみてください。 使い方次第では非常に使いやすいです。 (個人的に「JSONオブジェクト」と呼んでますが、一種の連想配列ですね。) 配列にして NewClass=[1, 2, function(){alert('わん');}]; とすると、それぞれ NewClass[0]、NewClass[1]、NewClass[2] でアクセス出来ますが、 NewClass=[function(){alert('わん');},1,2]; としてしまうと、NewClass[0]の内容が変わってしまいます。 JSONでは、つねにNewClass['ClassValue1']でアクセス出来ますから、 代入(作成)するときの順番が変わっても問題になりません。 ただし、ループさせるときは、 for(var i=0;i<NewClass.length;i++){} ではなく for(var i in NewClass){} を使ってください。 (Safariでは配列に対して in は使えませんので、ループで取り出すときは調整しなければなりません。) > document.write( ClassTest.ClassValue1 ); > document.write( ClassTest.ClassValue2 ); この出力を実現させるだけなら、関数オブジェクトでもJSONでもどちらでも可能です 関数オブジェクト(コンストラクタを使う) function NewClass(){ this.ClassValue1=1; this.ClassValue2=2; } ClassTest=new NewClass(); オブジェクト初期化子(JSON)を使う ClassTest={ClassValue1:1, ClassValue2:2}; > ANo.1回答 > 「JavaScriptでユーザ定義のclassを作る練習」でした。 ということをしたいのであれば、関数オブジェクト(function~)を使って、newしてください。 > ↑この部分では、NewClassのメンバーを一気に定義しているのですが、 > この方法がまず誤っていますか?? 文法としては間違ってはいないんですが、 生成された物や目的が違うので何とも言えないです。

zuntata99
質問者

お礼

回答ありがとうございます。JSONという書き方(?)なのですね。 @ITのほうで、簡潔な書き方として紹介されていたので、そっちの意味を理解して使おうと考えたのがつまづきのもとでした。 ご教示頂いた方法とこれまでご回答頂いた件をあわせて、 理解の低いうちは、素直にfunctionキーワードで定義していくことにします。 こちらの回答も、また後日読み返させていただきたいと思います。

  • urdapple
  • ベストアンサー率30% (9/30)
回答No.5

ごめんなさい。 プロパティーの生成方法としては NewClass = { ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} } でもイイみたいですね<(>o<)> やべ、俺も素人丸出し~⌒⌒⌒⌒⌒/(;x~x)\<ごめん

zuntata99
質問者

お礼

いえ、回答ありがとうございます。 僕もこの指定方法にはものすごい違和感があります。

  • urdapple
  • ベストアンサー率30% (9/30)
回答No.4

ん~~そもそもJavaScript(以下:「JS」)で「クラス」を定義するというのが難しい気もしますが・・・ JSにおいてコンストラクタとはクラス(のような物)を定義する関数のことを言います。 なので・・・ function Point(x, y) { //ユーザ定義クラスの作成?  this.x = x; //クラスメンバーの定義?  this.y = y; //クラスメンバーの定義? } これはコンストラクタであり、クラスの宣言でもあります。 一見するとただの関数ですけど、Pointというクラスのコンストラクタです。 その後「Point」クラスのオブジェクトを生成する時は・・・ [オブジェクト名] = new Point([プロパティーx],[プロパティーy]); とすべき。 ちなみにエラーログでは NewClass is not a constructor って言われちゃっています。この場合のconstructorは、オブジェクトの生成元を参照するプロパティーとしてのコンストラクターでしょうから・・・ 「NewClass = {ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');}}って、NewClassオブジェクトに対していろいろやろうとしてるみたいだけど、そもそもNewClassって参照元は存在しないぜ!」 って言われちゃってんだと思います。 つまり・・・ NewClass = { ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} } このソースではコンストラクタとして不十分だということです。 というか、そもそも変数としてのClassValue1やClassValue2に対して、「:」(コロン)で値を代入するというやり方が、JSで許されているのかがわかりません。こういったスタイルシートチックな数値代入の方法って正規にJSに存在するのかしらん?

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

とりあえずnewが無いのはただのミスだと思います。 (newが無いとただの関数呼び出しになってしまうので。) > このコードの場合、クラスの定義はどこで、コンストラクタはどれになるのでしょうか? > また、オブジェクトの生成(インスタンス?)はどこで行っているのでしょうか? まず、JavaScriptはプロトタイプベースのオブジェクト指向言語で、 C++やJavaのようなクラスベースとは勝手が違うところがあります。 詳しくは"プロトタイプベース"などで検索してもらえば何となく分かると思いますが、 例えば以下のような解説ページが見つかります。 http://developer.mozilla.org/ja/docs/Core_JavaScript_1.5_Guide:Class-Based_vs._Prototype-Based_Languages (他の言語に比べると変わった言語ですが、使ってみるとなかなかおもしろいですよ。) > クラスの定義 とくにクラスの定義と呼べるような部分はありません。 (強いて言うならコンストラクタかな…) > コンストラクタ この場合、関数オブジェクトPointがコンストラクタです。 関数オブジェクトにnew演算子を付けて呼び出すことで、 関数オブジェクトはコンストラクタとして呼ばれます。 > オブジェクトの生成 new演算子があるところで生成されます。 またプロパティ(メンバ変数)は動的に追加できるので、 コンストラクタでプロパティを設定していなくても、  var p = new Point(10, 20);  p.z = 30; などとできます。 > #1の補足 > ↑この部分では、NewClassのメンバーを一気に定義しているのですが、 > この方法がまず誤っていますか?? NewClassのプロパティ設定方法としては間違っていませんが、 これだとNewClass自身がClassValue1やClassValue2をプロパティに持つ オブジェクトになります。 (その前のfunction NewClassは上書きされているとおもいます。) コンストラクタは関数オブジェクトでなくてはならないので、 関数オブジェクトではないNewClassはコンストラクタになれません。 JavaScriptでオブジェクトを使うなら、 以下の記事も参考になると思います。 http://codezine.jp/a/authorlist.aspx?auid=167 「著者情報」内の「関係記事」

zuntata99
質問者

補足

詳細なフォローありがとうございます。 なるほど。すこしわかった気がします。オブジェクトと関数オブジェクトは異なるもので、宣言(?)時にプロパティを定義してしまうと、オブジェクトになってしまうので、コンストラクタとしては使えない、ということですね。 (1)function NewClass(){    /*ここが誤っている?*/ // } (2)NewClass = { ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} } (1)で定義したオブジェクト(?)が(2)で上書きされた結果オブジェクトになっているので、コンストラクタとしては使えない、のでFireFox2がエラーを出した。ここまでの理解はあっているでしょうか?? (1)と(2)の違いは、プロパティやメソッドを定義したかしないかだと 思うのですが、ということは、プロパティやメソッドを定義してしまうと、関数オブジェクトにはならないということでしょうか?

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

すでに回答がありますが、せっかく書いたのでとりあえず。 ------------------------------------------------------ <script type="text/javascript"> //コンストラクタ function NewClass(){ //プロパティ this.ClassValue1 = "value1<br>"; //プロパティ、this.ClassValue2と書くのと同じ this["ClassValue2"] = "value2<br>"; alert('わん'); } //メソッド NewClass.prototype.method1 = function(a){ return "method1:"+a+"<br>"; } var ClassTest = new NewClass(); document.write( ClassTest.ClassValue1 ); document.write( ClassTest.ClassValue2 ); document.write( ClassTest.method1("test") ); </script> ------------------------------------------------------ > webで調べても正しいコンストラクタの書き方 というのが見つけ切れませんでした。 このページはどうですか? http://www.tokumaru.org/JavaScript/

zuntata99
質問者

補足

参考コード、およびwebサイトありがとうございます。 参考サイトでは、 function Point(x, y) { this.x = x; this.y = y; } var p = Point(10, 20); document.writeln("p(", p.x, ", ", p.y, ")"); というコードが紹介されていますが、 ??の部分が理解できません。 このコードの場合、クラスの定義はどこで、コンストラクタはどれになるのでしょうか?また、オブジェクトの生成(インスタンス?)はどこで行っているのでしょうか? function Point(x, y) { //ユーザ定義クラスの作成? this.x = x; //クラスメンバーの定義? this.y = y; //クラスメンバーの定義? } var p = Point(10, 20); //??newを使わずにオブジェクトを生成? document.writeln("p(", p.x, ", ", p.y, ")");

  • urdapple
  • ベストアンサー率30% (9/30)
回答No.1

何がしたいのか微妙にわからないんですが、とりあえず・・・ <script type="text/javascript"> /* メソッド的にfunctionを作成する。後でクラス(?)作成時に内封する。 */ function NewClass_ClassFunc() {  alert("わん"); } function NewClass() {  this.ClassValue1 = 1; /* この2つは定数みたいに扱えればいいのかな? */  this.ClassValue2 = 2; /* ならこれで一応動くよ */  this.ClassFunc = NewClass_ClassFunc; /* <-メソッド的に入れる */ } var ClassTest = new NewClass(); document.write(ClassTest.ClassValue1); document.write(ClassTest.ClassValue2); </script> これで「12」って表示されるけど、こんなんでイイのかな?(^-^;

zuntata99
質問者

補足

すみません、12と表示を事を実現する為には だとおかしくなりますね。 このコードでやりたかったのは、 「JavaScriptでユーザ定義のclassを作る練習」でした。 NewClass = { ClassValue1:1, ClassValue2:2, ClassFunc:function() {alert('わん');} } ↑この部分では、NewClassのメンバーを一気に定義しているのですが、 この方法がまず誤っていますか?? 誤っていない場合、なぜFireFox2は ClassTest = new NewClass(); の部分で、「NewClass」が コンストラクタではない というエラーを出したのでしょうか?

関連するQ&A

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

    ネットで検索したりして調べているのですがいまいちわからなかった箇所が あるので質問させていただきます。 コンストラクタで設定するのとプロトタイプで設定する違いがいまいちわかりません。 例えば 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>

  • コンストラクタすると同時にメソッドをオーバーロードするには?

    コンストラクタすると同時にメソッドをオーバーロードするには? リスナー関数でthisの参照先が変わってしまう問題に悩んでいます。 <!-- 方法(1) コンストラクタした後にメソッドを上書きする --> <p id="Test">test</p> <script type="text/javascript"><!-- function Hello (value){ this.value = value ? value : 'Hello, World!'; } Hello.prototype.start = function (event) { alert(this.value); } var world = new Hello(); var start = function (event) { world.start.call(world, event); }; // thisがworldを参照するようにstartメソッドを作り直す document.getElementById('Test').addEventListener('click', start, false); //--></script> 上記コードは期待通りの動作ですが、せっかくコンストラクタしたにも関わらず、メソッドを上書きしなくてはなりません。 コンストラクタした時点でstartメソッドが完成しているのが理想です。 (以下、全角空白は半角空白に置換してください) <!-- 方法(2) クロージャでメソッドを生成する --> <p id="Test">test</p> <script type="text/javascript"><!-- function Hello (value) {  function start (event) {   alert(this.value);  }  this.value = value ? value : 'Hello, World!';  this.start = (function(that){   return function (event) {    start.call(that, event);    that = null;   };  })(this); } var world = new Hello('Hello, World2!'); document.getElementById('Test').addEventListener('click', world.start, false); //--></script> こちらは完全に期待通りの動作を示しますが、prototype を使用していないのが少し気になります。 <!-- 方法(3) クロージャで prototype.start を上書きする --> <p id="Test">test</p> <script type="text/javascript"><!-- function Hello (value) {  this.value = value ? value : 'Hello, World!';  this.start = (function(that, start){   return function (event) {    start.call(that, event);    that = start = null;   };  })(this, this.start); } Hello.prototype.start = function start (event) {  alert(this.value); }; var world = new Hello('Hello, World2!'); document.getElementById('Test').addEventListener('click', world.start, false); //--></script> 結果としては期待通りのコードになったのですが、以下の点が気になっています。 ・方法(2)、方法(3) を比較すると、それぞれどのようなメリット、デメリットがあるのか。(prototypeが高速と聞いてからは (3) に傾いているのですが、よくわかっていません) ・コンストラクタ時に発動する特別なメソッド、プロパティが用意されているのか。 ・クロージャを使わずに解決できるのか。 ・全く別の方法(もっと良い実装)があるのか。 コードの書き方は千差万別だとは思いますが、主観で結構ですので、アドバイスいただければ幸いです。 # start() はサンプル故に短いコードですが、実際には比較的長いコードがある状態を想定しています。

  • JavaScriptでコンストラクタについて

    現在、JavaScriptを勉強中なのですが、 コンストラクタについて質問です。 下記のようなコードの場合、document.getElementByIdで取得したID 以外、使いまわしが出来ませんが、 コンストラクタを使って、1ページで複数使用出来るようにするには、 どのように記述すれば良いのでしょうか? //-----JavaScript----- function addEvent(elm,listener,fn){ try{ elm.addEventListener(listener,fn,false); }catch(e){ elm.attachEvent("on"+listener,fn); } } var c,y,m,d; addEvent(window,"load",function(){ c = document.getElementById("customer_birthday_c"); y = document.getElementById("customer_birthday_y"); m = document.getElementById("customer_birthday_m"); d = document.getElementById("customer_birthday_d"); if(c.options[0].selected == true){ y.disabled = true; m.disabled = true; d.disabled = true; } }); //-----JavaScript----- どなたかご教授ください。 宜しくお願いいたします。

  • useless setTimeout cal 

    すみません。教えて下さい。 下のコードを書いて、動きはするんですが、実行後に 「useless setTimeout cal」というエラーが出てしまいます。 エラーを回避したいのですが、どうすればいいのでしょうか。 IE6/IE8/firefox3.6 などで試しました *********************************** <html> <head> <script type = 'text/javascript'> function item(){ var i = 0; write(); function write(){ document.write(i+"<br>"); i ++; if(i<10){setTimeout(write(),100);} } } </script> </head> <body> <script type = 'text/javascript'>item();</script> </body> <html> ***********************************

  • JavaScriptの論理演算子について

    JavaScriptの論理演算子について質問です。 「alert(e.target||e.srcElement);」の結果がtrue かfalseではなくて「object HTMLHtmlElement」となるのは何故なのでしょうか? JavaScriptでは"||"は論理演算子ではないのでしょうか? ----------------------------------------------------------------------- <body> <a id="id1">Textarea</a> <script> (function () {   var i = document.getElementById ("id1");   document.addEventListener("dblclick", addEL, false);   function addEL (e) { alert(e.target||e.srcElement);   } }) (); </script> </body>

  • イベントの関数について、よくわからないことがあります。

    イベントの関数について、よくわからないことがあります。 (1)引数をセットしない関数と window.document.onmousemove = f; function f(evt) { alert(evt); } (2)無名関数?に引数 window.document.onmousemove = function(e) { alert(e); } (1)(2)は同じ動作なのですが、window.document.onmousemoveにセットする関数の引数は 特殊なのでしょうか?

  • validateForm firefoxでalertが表示されません

    java scriptについて質問です。 ホームページ内のプルダウンメニューで、項目が選択されていない状態で「submit」ボタンが押された場合、「~を選択してください」というメッセージを表示させたいと思います。 そこで以下のようなfunction validateFormを書いたのですが、alertがIEでは表示されるのにfirefoxでは表示されません。 function validateForm() { if (document.form1.Prop1.options.value == 'Error') { alert('Please select aaa.') document.form1.Prop1.focus() return false } if (document.form1.Prop2.options.value == 'Error') { alert('Please select bbb.') document.form1.Prop2.focus() return false } if (document.form1.Prop3.options.value == 'Error') { alert('Please select ccc.') document.form1.Prop3.focus() return false } if (document.form1.Prop4.options.value == 'Error') { alert('Please select ddd.') document.form1.Prop4.focus() return false } if (document.form1.Prop5.options.value == 'Error') { alert('Please select eee.') document.form1.Prop5.focus() return false } } firefoxでもalertを表示させるには、どのようにすればいいでしょうか? 教えてくださいませ。よろしくお願いします。

  • jQueryを使用してxmlを取得 ieでエラー

    wordpressで固定ページからxmlを出力するテンプレートを選択してます。 ページにアクセスした時に吐き出されるxmlは <?xml version='1.0' encoding='UTF-8' ?> <common> <days>01</days> <days>02</days> <days>03</days> <days>04</days> <days>05</days> <days>06</days> </common> です。 別のhtmlファイルの方でjQueryで <script> $(document).ready(function () { $.ajax({ type: "GET", url: "xmlをはきだすアドレス", dataType: "feed", success: xmlParser, error: function(){ alert('Error loading XML document'); } }); }); function xmlParser(xml) { alert($(xml).children("days").length); } </script> と書いています。 この場合firefoxやsafari,chromeではalertで6と表示されますが ie6,7,8だと0となってしまいます。 どなたかieでもalertで6と表示させる方法を知っている方いませんか?

  • jqueryでajaxsuccessの内側this

    いつもお世話になっております jqueyで質問なのですが、ajaxの成功したときに起動する successの内側で$(this).val()を呼び出し、CSSにアクセスしたいのですが 期待した動作にはなりません。 期待する動作 それぞれクリックすると「1」「2」「3」と出て背景が赤くなる。 実際の動作 エラー「e.nodeName is undefined」となります。 どなたか、successの内側から$(this)にアクセスする方法をご存知の方いらっしゃいませんでしょうか 他の方法で期待の結果になるようにではなく、successの内側から$(this)にアクセスする方法が知りたいです お忙しい中恐縮ですが、分かる方がいたら嬉しいです <input class="hoge" value="1" /> <input class="hoge" value="2" /> <input class="hoge" value="3" /> <script type="text/javascript"> $(document).ready(function() { $('.hoge').click(function(){ $.ajax({ url: "some.html", cache: false, success: function(){ alert( $(this).val() ); $(this).css('background-color','red'); } }); }); }); </script>

  • 入力した文字をalertで表示するスクリプトを作っています。

    入力した文字をalertで表示するスクリプトを作っています。 以下、IEとOperaでは動作しますが、FirefoxとGoogle Chromeでは動作しません。 書き方が悪いのでしょうか? <html> <head> <script language=JavaScript> <!-- function test(){ alert(input1.value); } // --> </SCRIPT> </HEAD> <BODY> <input type="text" name="input1"> <input type="button" value="テスト" onClick="test()"> </html>

専門家に質問してみよう