• 締切済み

thisで定義したプロパティが継承できない

以下のようなコードがあります。 function inherit(subClass, superClass) { for (var prop in superClass.prototype) { if (typeof(subClass.prototype[prop]) == "undefined") { subClass.prototype[prop] = superClass.prototype[prop]; } } } /* class Personal */ { function personal() { this.sex = "男"; } personal.prototype = { "hello" : "こんにちは", "fName" : "苗字", "lName" : "名前", "age" : "年齢" } } /* class Taku17 */ { function taku17() { this.lName = "taku17"; } taku.prototype = { "fName" : "Secret", "age" : 21, "tall" : "1234cm", "height" : "5678Kg", "getFullName" : function() { return this.fName+" "+this.lName; } }; inherit(taku17, personal); } var source = ""; window.onload = function() { var person1 = new taku17(); source += "person1.hello = "+person1.hello+"<br />"; source += "person1.fName = "+person1.fName+"<br />"; source += "person1.lName = "+person1.lName+"<br />"; source += "person1.age = "+person1.age+"<br />"; source += "person1.sex = "+person1.sex+"<br />"; source += "person1.tall = "+person1.tall+"<br />"; source += "person1.height = "+person1.height+"<br />"; source += "person1.getFullName() = "+person1.getFullName()+"<br /><br />"; document.getElementById("result").innerHTML = source.replace(/undefined/g, "<font color=\"#ff0000\">undefined</font>"); } Javascriptでクラス化と継承を実現するためのコードなのですが、出力される情報のうちsexの情報だけがundefinedになってしまいます。sexプロパティはpersonal関数(コンストラクタのつもり)内にthis.sexとして定義してあり、他のプロパティはprototypeで定義してあります。このsexプロパティも継承するにはどのようにしたら良いのでしょうか?色々試してみましたが、そもそもsexプロパティにアクセスする方法から分かりません。

みんなの回答

  • susie-t
  • ベストアンサー率86% (37/43)
回答No.2

すみません、No1の参考URLはprototype.jsに関するものでした。prototype.jsを使わないのであれば無用です^^;

  • susie-t
  • ベストアンサー率86% (37/43)
回答No.1

あまり綺麗ではないですが、以下でどうでしょう。 ---------------------------------------- <html> <head> <script> function inherit(subClass, superClass) { for (var prop in superClass.prototype) { if (typeof(subClass.prototype[prop]) == "undefined") { subClass.prototype[prop] = superClass.prototype[prop]; } } } /* class Personal */ { function personal() { this.initializePersonal(); } personal.prototype = { "initializePersonal" : function(){ this.sex = "男"; }, "hello" : "こんにちは", "fName" : "苗字", "lName" : "名前", "age" : "年齢" } } /* class Taku17 */ { function taku17() { this.initializeTaku17(); } taku17.prototype = { "initializeTaku17" : function(){ this.initializePersonal(); this.lName = "taku17"; }, "fName" : "Secret", "age" : 21, "tall" : "1234cm", "height" : "5678Kg", "getFullName" : function() { return this.fName+" "+this.lName; } }; inherit(taku17, personal); } var source = ""; window.onload = function() { var person1 = new taku17(); source += "person1.hello = "+person1.hello+"<br />"; source += "person1.fName = "+person1.fName+"<br />"; source += "person1.lName = "+person1.lName+"<br />"; source += "person1.age = "+person1.age+"<br />"; source += "person1.sex = "+person1.sex+"<br />"; source += "person1.tall = "+person1.tall+"<br />"; source += "person1.height = "+person1.height+"<br />"; source += "person1.getFullName() = "+person1.getFullName()+"<br /><br />"; document.getElementById("result").innerHTML = source.replace(/undefined/g, "<font color=\"#ff0000\">undefined</font>"); } </script> </head> <body> <div id="result"></div> </body> </html> ----------------------------------------- 各コンストラクタ関数は、自オブジェクトのメソッドに処理を丸投げ。継承するサブクラス側では、同じように丸投げして、そのメソッド内で親関数のメソッドを呼び出しています。この際、メソッドの名前が重複しないように注意してください。 この場合、Javaではsuperを使えばいいのですが、JavaScriptにはその機能はないので・・・。(独自に拡張されている方もいます。参考URLを参照してください。)

参考URL:
http://d.hatena.ne.jp/reinyannyan/20051118/p1

関連するQ&A

  • thisとvar ?

    javascript初心者です。 コンストラクタ(プロトタイプ)とクロージャを学んでいますが、 コンストラクタ(プロトタイプ)では、関数内にthisで変数宣言、クロージャはvarで宣言しています。 この違いの理由は何でしょうか?漠然とした質問ですみません。 thisとvarでの変数宣言の違いなど教えていただけないでしょうか? コンストラクタ-------------------- function Person(n){ this.name = n; } Person.prototype.city = 'Tokyo'; Person.prototype.moveTo = function(c){ document.write(this.name + ': Moving to... ' + c + '<br>'); Person.prototype.city = c; } クロージャ------------------- function Person(n, a){ var name = n; var age = a; return { getName: function() { return name; }, setAge: function(i){ if( 0<= i ){ age = i; } }, getAge: function(){ return age; } } }

  • javascriptのconstructorプロパティについて

    constructorプロパティとは、 オブジェクトの初期化で使用されたコンストラクタ関数を参照 とのことなので、下記2パターンのPGを作成しました 1.prototypeの明記なし function Hoge(){ this.init = "Hogeで初期化"; this.getInit = function(){ return this.init; } } var obj = new Hoge(); alert(obj.constructor == Hoge); for(prop in obj){ alert( prop + " - " + obj[prop]); } //実行結果 True init - Hogeで初期化 getInit - function () { return this.init; } 2.prototypeの明記あり function Hoge(){ this.initialize.apply(this,arguments); this.init = "Hogeで初期化"; this.getInit = function(){ return this.init; } } Hoge.prototype ={ initialize:function(){ this.init = "Hoge.prototype.initializeで初期化"; }, getInit:function(){ return "Hoge.prototype.getInit()"; } } var obj = new Hoge(); alert(obj.constructor == Hoge); for(prop in obj){ alert( prop + " - " + obj[prop]); } //実行結果 false init - Hogeで初期化 getInit - function () { return this.init; } initialize - function () { this.init = "Hoge.prototype.initialize\u3067\u521D\u671F\u5316"; } ・質問内容 prototypeの明記なしの場合は、Hogeのコンストラ関数を参照している(結果がTrueのため) prototypeの明記ありの場合は、falseのためコンストラ関数を参照していないのですが、 prototype明記あり、なしで結果が異なる理由が分からない状態です。 (prototype.constructorにも手を出したのですが、上記が解決しないため  constructorプロパティに関してのみ質問した次第です) ネット、書籍等で調べたのですが、検討がつかない状態です。 お手数ですが、ご教授お願い致します。

  • PHPのクラス継承において質問

    class SuperClass{ public function getSuperClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } } class SubClass extends SuperClass{ public function getSubClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } $obj = new SubClass(); print "<br />"; $obj -> getSuperClassName(); print "<br />"; $obj -> getSubClassName(); 上記のようなコードがあった場合、 出力結果は SubClass SuperClass //継承しているにもかかわらず、SuperClassという文字列が返る。 SubClass SubClass と上記のようになります この結果に一点疑問があるのですが、親クラスのメソッドは子クラスに継承されるんですよね? であれば親クラスの public function getSuperClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } の箇所の print __CLASS__; の記述箇所はSubClassとでなければいけないような気がします。 しかし結果はSuperClassとでますが、このメソッドは子クラスに継承されていないのですか? publicなら継承されるとマニュアルにかいてありましたが、どうなっているのでしょうか よろしくご教授御願い致します。

    • ベストアンサー
    • PHP
  • コンストラクタと静的メソッドを簡単に定義する

    立て続けに質問することをお許し下さい。。 以下のような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 : "白色人種" }; /********************************************/ 多分、初めに行ったコンストラクタの定義とこの{}の定義とが競合しているためだと思うのですが、何かよい書き方ありませんでしょうか。

  • setTimeoutのthis参照について

    prototypeメソッドの中でsetTimeout関数を使用したところ、thisで自身の関数を参照しなくなりました。setTimeoutの挙動についてぐぐってみたのですが、いまいちsetTimeoutを使用したときのスムーズな記述方法がわかりません。 ******************************** var hoge=function(){ this.myName="ほげ"; } hoge.prototype={ init:function(){ setTimeout(function(){ hoge.prototype.displayName(); // ★(1)setTimeout関数の中でのメソッドの適した呼び出し方は? // ↑の記述でも呼び出せるけど、間違ってる気がする。。 },1000) }, displayName:function(){ // ★(2)ここでhogeオブジェクトのmyNameプロパティを参照するにはどう記述すれば良いのか? //console.log(this.myName); //↑setTimeoutを使ったのでthis参照はwindowオブジェクトになっているから違う //console.log(hoge.myName); →undefinedを返す } } window.onload=function(){ var a=new hoge(); a.init(); } ******************************** 上記のようなprototype関数を使用したときのスムーズな記述方法を教えていただけませんでしょうか。 知りたいのは下記2点です。 ★(1)prototypeメソッドを使用したとき、setTimeout関数の中でのメソッドの適した呼び出し方は? ★(2)setTimeout関数内で呼び出したメソッドから、自身のオブジェクトのプロパティを参照するにはどう記述すれば良いのか? 初心者なので説明が下手だったり、質問内容で間違った記述があるかもしれません。 質問内容で問題がありましたらご指摘いただけると助かります。

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

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

  • Javascriptの書き方

    素朴な質問なんですが、 JavaScriptを書くとき、全部左寄せにそろえて 良いのでしょうか? 下のように、段差があったほうがいいのでしょうか? function toStringOfPerson() { return (this.name + " / " + this.age); } function Person(name, age) { this.name = name; this.age = age; this.toString = toStringOfPerson; } ホームページを作成中、 半角スペースが2つ、3つ重なったところを 一括変換していて、疑問がわきました。

  • javascript new演算子について質問があります。

    javascript new演算子について質問があります。 只今javascript勉強中なのですが、どこかのサイトでnew演算子は悪いパーツとの 記事を読みました。 そこでnew演算子を使用せずにオブジェクト生成の方法を試行錯誤考えてみたのですが (IE用に__proto__もなしで)例えば以下コードはアリなコードでしょうか?? あるいはありえない感じでしょうか?? またnewが悪なのはインスタンスを作る時にnewを付け忘れると、 グローバルな汚染をしてしまうということだけなのでしょうか?? オブジェクトとプロトタイプの理解に苦しんでいるところなので 色々と曖昧なのですが、どなたかどうぞご教授お願い致します。 var obj = {}; obj.method = function(){ this.prop1 = "hoge" return this; }; obj.method.prototype = obj.method(); obj.method.prototype.prop2 = "fuga"; var obj2 = obj.method(); console.log(obj2)

  • callについて

    http://www.tohoho-web.com/js/object.htm#inheritClass function Person2(name, age, email) { this.email = email; Person.call(this, name, age); } ここのHPにあるこの文にcallが使われていますが thisはPerson関数をさしているのでしょうか? 一番目の引数にある関数に、残りの引数を渡すと思っているのですが thisのところにnullがある場合はどうなるのでしょうか? (他のスクリプトですがcall(null ,hoge,hoge)という使われ方をしているのを見ました) またnullの場合とthisの場合の違いも教えていただけると嬉しいです。 できる範囲でいいので解説お願いいたします。 質問の意味がわからず補足が必要な場合は遠慮なく補足要求してください。

  • php クラス

    phpエクラスの勉強をしているのですが、参考書に書いているメンバ変数に値を代入している意味がよくわからないので教えてください。メンバ変数の値を書かなくtも動作できるのになぜ必要なのでしょうか? 参考書 <html> <head> <title>サンプル</title> </head> <body> <?php $pr = new Person; $pr->name = "鈴木"; $pr->age = 56; ?> <table border="2"> <tr bgcolor="#AAAAAA"> <th>名前</th> <th>年齢</th> </tr> <?php print "<tr><td>"; print $pr->getname(); print "</td><td>"; print $pr->getage(); print "</td></tr>"; ?> </table> <?php class Person { public $name ="姓名"; public $age = 20; function getname(){return $this->name;} function getage(){return $this->age;} } ?> </body> </html> テスト <?php class Person { public $name ;←ここに値を格納する意味 public $age ;←ここに値を格納する意味 function getname(){return $this->name;} function getage(){return $this->age;} } ?>

    • ベストアンサー
    • PHP

専門家に質問してみよう