• ベストアンサー

コンストラクタと静的メソッドを簡単に定義する

立て続けに質問することをお許し下さい。。 以下のようなPersonクラスがあるとします。 /**** Person クラス(全角スペース表記) ****/ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <HTML>  <HEAD>   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">   <META HTTP-EQUIV="Content-Script-Type" CONTENT="javascript">   <TITLE>教えて!gao</TITLE>   <SCRIPT TYPE="text/javascript">    function Person(name, age, sex, color) {     this.name = name;     this.age = age;     this.sex = sex;     this.color = color;    }    Person.prototype = {     name:null,     age:null,     sex:null,     color:null    };    Person.YELLOW = "黄色人種";    Person.BLACK = "黒色人種";    Person.WHITE = "白色人種";    function test() {     var person = new Person("ggaogg", 23, "male", Person.YELLOW);     var resultBlock = document.getElementById("resultBlock");     for (property in person) {      resultBlock.appendChild(document.createTextNode(property + " = " + person[property]));      resultBlock.appendChild(document.createElement("BR"));     }    }   </SCRIPT>  </HEAD>  <BODY ONLOAD="test()">   <DIV ID="resultBlock"></DIV>  </BODY> </HTML> /********************************************************/ これの実行結果は、以下の通りです。 name = ggaogg age = 23 sex = male color = 黄色人種 しかし、静的変数を、毎回「Person.」を付けて記述するのは面倒で、すべて{}でひとくくりになっていたほうが可読性も増すと思い、以下のようにできると思いましたが、そうしたところ new Person("ggaogg", 23, "male", Person.YELLOW); の部分がコンストラクタではないというようなエラーとなってしまいます。(Web等でこの書き方はあまり見かけないが自分は気に入っている) /************ 変更した部分 ******************/ Person = { YELLOW : "黄色人種", BLACK : "黒色人種", WHITE : "白色人種" }; /********************************************/ 多分、初めに行ったコンストラクタの定義とこの{}の定義とが競合しているためだと思うのですが、何かよい書き方ありませんでしょうか。

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

  • ベストアンサー
  • arexis
  • ベストアンサー率66% (66/99)
回答No.3

あ、質問がなんとなくわかりましたが、説明が難しい。 /* 書換え前 */ Person.YELLOW = "黄色人種"; Person.BLACK = "黒色人種"; Person.WHITE = "白色人種"; の部分だけを /* 書換え後 */ Person = { YELLOW : "黄色人種", BLACK : "黒色人種", WHITE : "白色人種" }; と単に簡略化したいと言う事でしょうか? 書換え後の方法でPersonに後から追加してるつもりなら、 この書き方では『追加』にならずに新たな Person 変数(オブジェクト)を定義してるだけ。 同じ名前を持つ コンストラクタ function Person(){} がこの時点で消滅します。 また、prototypeで追加の形をとれば、それらはコンストラクタとして呼ばれた時に全てを生成してしまいます。 そもそも書換え前の時点でも Personをコンストラクタとして用意しながら、 オブジェクトとして別利用(間借りしてるような物)してるので、それ自体が目的とする意図ともしかしたらずれてるかもしれないと思います。 コンストラクタとなる function Person の中で #2の方法などで this.colorを定義する時に 引数colorの値に応じて動的に定義させるか、 colorに渡す引数を別の場所でオブジェクトとして定義しておきたいなら、 col = { YELLOW : "黄色人種", BLACK : "黒色人種", WHITE : "白色人種" }; var person = new Person("ggaogg", 23, "male", col.YELLOW); の様に Personではなく、別の名前にすれば普通に成り立ちます。 ちょっと考えすぎて迷路に入ってませんか? ^^;

ggaogg
質問者

お礼

>と単に簡略化したいと言う事でしょうか? そうそう、そうなんです。 長くJavaのスタイルに慣れてしまったせいで、現在JavaScriptの書き方に当惑中です。。 #2の方法ですが、ハッシュを一時的に作成して、そこから値を取り出すということが、#3を読んでようやく分かりました。 残念ながら#2は今回求めていた答えそのものではなかったですが、こんな書き方も面白いですね。 定数だけ別のクラスに定義する方法は、無難ではありますね。 そもそもC言語とかだと名前空間も何もないところにdefineしているわけですし、Cの後にJavaを学習したときにも、「クラスの外に定数宣言できないかな・・」と考えていたことを思い出しました・・。 というわけで、なんだか色々と考えて頂いちゃったみたいですけど、JavaScriptの流儀でやろうと思います。 言語仕様で簡単に素直に実現することが難しいということが分かっただけでも収穫でした。 どうもありがとうございました。

その他の回答 (2)

  • arexis
  • ベストアンサー率66% (66/99)
回答No.2

質問者さんの作ろうとしてる物と意図が同じになるかわかりませんが function Person(name, age, sex, color) { this.name = name; this.age = age; this.sex = sex; this.color = {YELLOW:"黄色人種",BLACK:"黒色人種",WHITE:"白色人種"}[color]; } function test() { var person = new Person("ggaogg", 23, "male", 'YELLOW'); var resultBlock = document.getElementById("resultBlock"); for (property in person) { resultBlock.appendChild(document.createTextNode(property + " = " + person[property])); resultBlock.appendChild(document.createElement("BR")); } } これで事が足りるでしょうか?

  • ai10
  • ベストアンサー率27% (3/11)
回答No.1

私が知っている限りでは withでしょうか…あまりオススメしませんが with( Person ) {   YELLOW = "";   BLACK = "";   WHITE = ""; } これでいけると思います。多分…。

ggaogg
質問者

お礼

先ほどの質問に続き、ありがとうございます。 調べてみると、javascript1.2で導入されたようですね。 こちらの環境では、Person.YELLOW、Person.BLACK、Person.WHITEは、いずれもundefinedになりました(IE7とFireFox2.0.0.12)。 さらに、ai10さんがおっしゃられるように、現在非推奨であるとの記述が多々あったので、これを使うのは避けようと思います。 しかし情報が見つからなかっただけでなく、実際にJavaScriptを使われている方でも使わない記述となると、私の求めるものはなんだか邪道に思えてきました。

関連するQ&A