• 締切済み

prototypeで前の値を潰さない方法は?

function obj() { this.name = "名前です"; } var obj01 = new obj(); alert(obj.name); というコードの場合、obj.nameでobj関数に設定されたnameプロパティの値「名前です」をアラートすることができます。このobj関数を変更せず、あとからプロパティと値を追加したい場合、prototypeメソッド(って言って間違いありませんか?)を用いて以下のように実現することができます。 function obj() { this.name = "名前です"; } obj.prototype.age = "年齢です"; var obj01 = new obj(); alert(obj.name+" / "+obj.age); newする前に記述するのがポイントなんですよね。これにより、obj関数(オブジェクト)にageというプロパティと値「年齢です」が追加され、アラートできるようになりました。また最近、連想配列を使うことで複数のプロパティと値を一気にセットできる便利な方法を発見しました。 function obj() { this.name = "名前です"; } obj.prototype.age = "年齢です"; obj.prototype = { "country":"日本出身です", "city":"東京出身です", "hobby":"音楽鑑賞です" }; var obj01 = new obj(); alert(obj.country+" / "+obj.city+" / "+obj.hobby); //alert(obj.age); //alert(obj.name); と、このように複数のプロパティと値をセットし、後で利用することができます。 前置きが長くてすみません、ここからが質問です。 最後の例の場合、連想配列によってセットされたプロパティの値は存在しますが、それ以前にprototypeで設定したageプロパティは存在しなくなっています。alert(obj.age)の行をコメントアウトしていますが、実行するとundefinedと表示されます。そして2つ目のコメントアウト行alert(obj.name);は問題なくnameプロパティの値をアラートできています。 つまり、prototypeメソッドを使って先に追加したプロパティと値は、「obj.prototype=連想配列」で実行した時点で潰されてしまっているようでした。 この連想配列を使ったプロパティ追加を行う際、先に「obj.prototype.プロパティ名」で追加していたプロパティと値を残しておく方法はありませんでしょうか?

みんなの回答

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

まず、prototypeはメソッドではなくてプロパティと呼ぶのが妥当です。オブジェクトの持つデータをプロパティ、振る舞い(関数)をメソッドと呼ぶので。 ご質問のようなケースでは、たとえばprorotype.jsではObject.extendというメソッドがよく使用されます。これと同じものをextend関数として定義して使用してみます。 -------------------------------------------------------- //prototype.jsのObject.extendから流用。 function extend(destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } function obj() { this.name = "名前です"; } obj.prototype.age = "年齢です"; obj.prototype = extend(obj.prototype, { "country":"日本出身です", "city":"東京出身です", "hobby":"音楽鑑賞です" }); var obj01 = new obj(); alert(obj01.age+" / "+obj01.country+" / "+obj01.city+" / "+obj01.hobby); -------------------------------------------- 提示されたコードを若干修正しています。obj.country等ではなくてobj01.country等だと思います。 余談ですが、newする対象の関数(クラス)の名前は先頭大文字、newした結果(インスタンス)は先頭小文字とするのが一般的だと思います。 参考になれば幸いです。

関連するQ&A

  • prototype の使い方

    prototype プロパティについて勉強しているのですが、次のような使い方で正しいのでしょうか。 var Dog = function() { this.sit = "I am sitting."; } var myDog = new Dog(); alert(myDog.sit); //“I am sitting.”と表示される。 var Dog2 = function() {} Dog2.prototype.sit = new Dog().sit; var myDog2 = new Dog2(); alert(myDog2.sit); //“I am sitting.”と表示される。 prototype の行で new Dog() を作るとゴミが出る気がするのですが、勝手に解放されるのでしょうか。

  • プロトタイプの関数から、別のプロトタイプの関数を呼出すには?

    javascript初心者ですが、オブジェクトに関してわからないことがあるので、教えてください。(とんちんかんな質問かもしれませんが、ご容赦下さい。) 下記のような場合、関数calから関数setを呼出すのはどうすればよいのでしょうか? function Obj(){ } Obj.prototype.set = function(){ } Obj.prototype.cal = function(){ ここから、setを呼出すにはどうすればよいのでしょうか? } var obj = new Obj();

  • JavaScript プロトタイプについて

    ●質問の主旨 下記のコードを書くとエラーとして、 TypeError: Cannot set property 'totalPrice' of undefined が返されます。なぜでしょうか?原因が分かりません。 個人的には、このコードで、totalPriceメソッドを定義しているつもりなのですが…。 お詳しい方がいらっしゃいましたら、ご教示願います。 ●コード function Menu(name, price) { this.name = name; this.price = price; } var hamburger = new Menu("ハンバーガー", 100); hamburger.prototype.totalPrice = function(quantity) { return this.price * quantity; } var cheeseburger = new Menu("チーズバーガー", 120); cheeseburger.prototype.totalPrice = function(quantity) { return this.price * quantity; } output("太郎は、" + hamburger.name + "を" + hamburger.totalPrice(5) + "円分買いました。"); output("二郎は、" + cheeseburger.name + "を" + cheeseburger.totalPrice(3) + "円分買いました。"); ●元ネタ CodeStudy Javascript 4.プロトタイプ その3 http://jeek.jp/study/section21/4

  • prototypeという予約後について

    prototype プロトタイプ・キーワード。オブジェクトにプロパティを追加するときに使用する。 とのことですが、以下の2つは異なるのでしょうか? (1)---------------- var M = function(){}; M.val = 1; ------------------- (2)---------------- var M = function(){}; M.prototype.val = 1; ------------------- どう違うのかヒントください。

  • 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プロパティに関してのみ質問した次第です) ネット、書籍等で調べたのですが、検討がつかない状態です。 お手数ですが、ご教授お願い致します。

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

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

  • prototype宣言によるメソッドと、プロパティを区別

    Array.prototype.myInclude = function(){ } というように配列にメソッドを追加しました。この上で hoge = new Array(); hoge["mikan"] = "orange"; hoge["ringo"] = "red"; for( var i in hoge ){ alert( i ); } とすると、 myInclude orange red と始めに追加したメソッドまで拾ってしまいます。 既にいくつかprototypeで書いてしまいました。 for~inの部分の書き換えでできる方法は無いでしょうか。

  • prototypeに二つ以上の暗黙の参照を持たせることはできない?

    var NAMESS = {   org:{ } } NAMESS.org = {   clsFoo : function( ){     this.foo = function( ){       alert("foo");     }   }   ,clsBar : function( ){     this.bar = function( ){       alert("bar");     }   }   ,clsHoge : function( ){ } } NAMESS.org.clsHoge.prototype = new NAMESS.org.clsFoo( ); NAMESS.org.clsHoge.prototype = new NAMESS.org.clsBar( ); 上記コードではclsHogeはclsBarのみ継承し、clsFooを継承できません。(代入しているので当たり前かもですが‥) これを NAMESS.org.clsHoge.prototype.foo = new NAMESS.org.clsFoo( ); NAMESS.org.clsHoge.prototype.bar = new NAMESS.org.clsBar( ); というようにする方法は知ってはいますが、 できればfooとbar両方を暗黙の参照にしたいと考えています。 JavaScriptでは二つ以上の継承はできないのでしょうか? よろしくお願いします。

  • 文字列と配列の振る舞いの違いについて

    以下のコードで出るalertが Array => 12 String => 2 となります。この原因といいますか原理をご存じでしたら教えていただけませんでしょうか。お願いします。 =========================================================== var test = function(name){ this.arr.push(name); this.str += name; } test.prototype = { arr:[], str:"" } var r = new test("1"); var z = new test("2"); alert("Array => " + z.arr.join("") + "\nString => " + z.str);

  • js プロトタイプ

    javascriptソースコード <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>サンプル</title> </head> <body> <script type="text/javascript" src="jquery-1.7.2.min.js"></script> <script src="fastclick.js"></script> <script> function print(str){ document.write(str + "<br />"); } function Car(manufact, name){ this.manufact = manufact; this.name = name; } Car.prototype.info = function(){return this.manufact + " " + this.name;}; document.write("<p>"); var car1 = new Car("Toyota", "PRIUS"); print(car1.info()); var car2 = new Car("Honda", "INSIGHT"); print(car2.info()); document.write("</p>"); </script> </body> </html> 23行目なのですが「 Car.prototype.info 」とありますがjsにおいてプロトタイプはオブジェクトだという事は認識しておりますがプロトタイプを宣言する意味は何があるのでしょうか? 参考urlです。 http://www.ajaxtower.jp/js/function_class/index3.html

専門家に質問してみよう