• ベストアンサー

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

以下のコードで出る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);

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

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

> 【コラム】そろそろきっちりJavaScript (6) プロトタイプチェーン(2) | エンタープライズ | マイコミジャーナル > http://journal.mycom.co.jp/column/js/006/index.html より引用。 | プロパティの "作成・変更" では、明示的に prototype を上書きしようとしない限り、そのオブジェクト自身のプロパティが作成・変更される。 よって、  this.str += name; とした場合は、test.prototype.strに影響はありません。 (alertでtest.prototype.strを確認してみてください。) この場合は、各オブジェクトごとにstrプロパティが作成され、 そこにnameの値が入るからです。 一方、  this.arr.push(name); では、this.arrはpushメソッドを呼び出すために「参照」されているので、 プロトタイプチェーンをたどってtest.prototype.arrの方が参照されます。 結果、pushメソッドにより配列オブジェクトtest.prototype.arrの内容(プロパティ)は変化します。 (test.prototype.arr自体は変更されていない。) もし、  this.arr = this.arr.concat(name); とした場合は、this.arrが「変更」されているので、 最初の場合と同様にtest.prototype.arrに影響はなく、 新たに各オブジェクトにarrプロパティが作成されます。

No_Smoking
質問者

お礼

なるほど。よく分りました。ありがとうございました。

その他の回答 (2)

  • OKwebb
  • ベストアンサー率44% (92/208)
回答No.2

newの仕様において、プリミティブ値 (文字列、数値、真偽値、undefined 、null)の場合は初期化されるし、オブジェクトの場合はそのまま設定されるということだと思います。

参考URL:
http://nanto.asablo.jp/blog/2005/10/24/118564
No_Smoking
質問者

お礼

ありがとうございます。リンクの紹介もありがとうございました。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

これはprototypeをいじる必要があるのでしょうか? 普通に・・・ var test = function(name){ this.arr=new Array; this.arr.push(name); this.str = new String; this.str += name; } ではいけないの?

No_Smoking
質問者

お礼

回答ありがとうございます。ご回答のコードで全く問題ございません。 ただnewにおけるprototypeの振る舞いが気になったので質問した次第です。実用的かどうかを抜きに「なぜそうなるのか?」が本件での疑問です。 あ、質問文で言い忘れましたがfirefoxでの結果です。

関連するQ&A

  • ある文字を含む文字列のみ配列にする

    何度もすみません。 array(XX) { [0]=> array(2) { ["text"]=> string(YY) "りんご美味しい" ["name"]=> string(Z) "あいこ" } [1]=> array(2) { ["text"]=> string(XX) "富士山登りたい" ["name"]=> string(Z) "みほ" } [2]=> array(2) { ["text"]=> string(XX) "動物園行きたい" ["name"]=> string(Z) "なほ" } [3]=> array(2) { ["text"]=> string(XX) "メロン美味しい" ["name"]=> string(Z) "ゆい" } [4]=> array(2) { ["text"]=> string(XX) "お腹すいた" ["name"]=> string(Z) "まこ" } [5]=> array(2) { ["text"]=> string(XX) "数学やだー" ["name"]=> string(Z) "あいこ" } ……… } のような配列$textがあり、そこから["text"]に $keyword = array("りんご","メロン") の文字列を含むものだけ取り出したいです。 今までもらった回答を参考に $key_text = array(); foreach($text as $key => $v1){ foreach($keyword as $v2){ if(strpos($v1[text], $v2) !== false){ $key_text[] = $key; } } } と書いてみたのですが、上手く動作しません。 よろしければどこが間違っているかご指摘ください。 お願いします。

    • ベストアンサー
    • PHP
  • JavaScriptでオブジェクトの配列

    function myfunc() {} で定義したようなオブジェクトを var arr = new Array(); arr.push()で配列に入れて、あとから取り出す際に arr[0]をmyfunc型として使うにはどうすればよいでしょうか? キャストのようなものも多分なさそうですし。

  • parseとtoStringの違い

    javascriptを勉強中です。 基本的な事かもしれませんが識者の方、宜しくお願いします。 以下のようなスクリプトで parseの部分をtoStringにすることで何が違ってくるのでしょうか? データの型?が違うのでしょうか? 御存じの方がいましたらご教授下さい。 function totest(str){ this.str = "abcdefg"; this.str += str; return this.str; } function test1(str){ this.str = str; this.parse = totest } var str = "aaa”; var p1 = new test1(str); alert(p1.str); alert(p1.parse(str));

  • 関数内での繰り返し処理の結果を配列で受け取りたい

    関数内でfor文で繰り返し処理を行い、 結果を配列として返すような関数を書きたいと思っています。 function hoge(){ var a = [1,2,3,4]; for (var i=0; i < a.length; i++){ a1 = "a" + i; var arr = new Array(); arr.push(a1); } return arr; } しかし、以下のように 関数hogeの結果を変数bで受け取ってみると、 配列の最後のデータしか表示されません。 var b = hoge(); alert(b); //a3のみが表示される a0, a1, a2, a3と表示されるようにするには、 どうしたらよいでしょうか。

  • 部分文字列に一致する番号を返す。

    お世話になります。 function StrNoTbl(Str,No){ this.Str=Str; this.No=No; } var htmlStr=new Array( new StrNoTbl('aaa',1), new StrNoTbl('bbbbbb',7), new StrNoTbl('cc',5) ); などと、配列を定義して、 ChkStr="xxxaaaxxx.html#xxx"; と、いう文字列に対して 1 を返す。 ChkStr="xxxccxxx.html#xxx"; に、対して 5 を返すなんてことできるのでしょうか。 for(){}で、やれば、できるのですが、 配列が大きいと、タイムロスが大きくなってしまいます。 正規表現で、できると思うのですが、よくわかりません。 なんとかご教示願えないでしょうか。 よろしくお願いします。

  • Arrayオブジェクトとforms配列

    以下のスクリプトを実行すると、(2)の所で「document.forms.GetFromArray is not found」 のエラーとなります。(ブラウザはFirefox)。 意図としてはArrayオブジェクトをカスタマイズして追加したGetFromArray()メソッドでforms配列を操作したいのですが... エラーメッセージからすると、「document.formsは配列(Arrayオブジェクト)では無い」と言っているようです。 この方法でforms配列を参照する方法を教えて下さい。 あるいは、Arrayオブジェクトではない、他のオブジェクトをカスタマイズするのでしょうか?お願いします。 <html> <head> <script type="text/javascript"> <!-- Array.prototype.GetFromArray=function(func){ for(var i=0;i<this.length;i++){ func(this[i]); } } function disp1(h){ alert(h); } function disp2(h){ alert(h.name); } function run(){ var array=new Array('dog','cat','fish'); array.GetFromArray(disp1); //(1) OK document.forms.GetFromArray(disp2); //(2) エラー } //--> </script> </head> <body> <form name="test"> <input type="text" name="bunrui" value="分類">/ <input type="text" name="detail" value="詳細">/ <input type="button" value="実行" onClick="run();"> </form> </body> </html>

  • 配列をソートしたいです

    配列をソートしたいです ArrayクラスのsortOn()を使って、 「x座標の大きい順」に順番をならべ変えたいのですが 上手く行きません。。 現在、配列を使い 3つの矩形のSpriteを配置しています。 ↓現在のコード ===================================== var arr:Array = new Array(); for(var i:int=0; i<3; i++){  arr[i] = new Sprite();  with(arr[i].graphics){   beginFill(0x666666);   drawRect(0,0,8,8);   endFill();  }  arr[i].x = i*10;  addChild(arr[i]); } ===================================== 今、各Spriteのxプロパティは  arr[0].x = 0;  arr[1].x = 10;  arr[2].x = 20; になっているのですが、 これをソートして  arr[0].x = 20;  arr[1].x = 10;  arr[2].x = 0; にならべ変えたいのですが、 どのように書けばいいのかがわかりません。。 今、このように書いてるのですが arr.sortOn(arr.x, Array.NUMERIC); 並べ替えができません、 (おそらく arr.x が駄目なのだと思うのですが。。) どなたかご存知の方いらっしゃいましたら どうかよろしくお願いいたします。

    • ベストアンサー
    • Flash
  • xmlから配列で取得したものを取り出したい

    as3初心者jpncan15といいます。 xmlから配列で取得したものをfunction外で取り出したいのですがどのようにすればいいのか悩んでいます。functionを調べたり配列を調べたり頭がかなり混乱中です。 お手数ですがご教授いただけますでしょうか? var ary:Array=new Array(); var ary_name:Array=new Array(); var loader:URLLoader = new URLLoader(); var request:URLRequest = new URLRequest("b.xml"); var xml:XML; loader.load(request); loader.addEventListener(Event.COMPLETE , XMLload); function XMLload(e:Event):void { xml = XML(e.target.data); num_txt.text = xml.item.length(); //xml件数をテキストフィールドへ入れる for each(var element:Object in xml.item.thumb) //配列に入れる {ary.push(element);} for each(var element_name:Object in xml.item.name) //配列に入れる {ary_name.push(element_name); trace(element_name);}//出力OK } //function外で配列を使用したい trace(ary[5]); trace(ary_name[2]);

    • ベストアンサー
    • Flash
  • 配列の受け渡し

    失礼致します。 配列について困っていまして、質問させてください。 今、フォームデータとしてsubmitを押したときにjavascriptから配列をサーブレットに受け渡ししたいです。フォームを含めたソースは次のようになります。 <script> function submitArr(n) { var i = 0; var array = []; while(i<n) { array.push(variable); // variableはiの値に応じて変わる変数。 } document.frm.array.value = array; ☆ } </script> <form action="servlet" method="post" name="frm"> <input type = "submit" value = "submit" onClick="submitArr()"> <input type = "hidden" value = "" name="array"> ☆ </form> 次に、servlet側でこれを受け取ります。 String[] array = new String[n]; ★ while(i<n) { array[i] = req.getParameter(array[i]); ★ } 以上が本質的な部分だと思うのですが、☆および★の部分をどう書いたらいいかわかりません。 添え字も少しあやふやなのですが、 分かる人がおられましたら、教えていただけないでしょうか?

    • ベストアンサー
    • Java
  • 二次元配列に値をセットしたいんですが

    ASP(html)での変数をJavaScriptに渡して 二次元配列を作成したいのですが、どうもうまくいきません。 どなたか、ご教授願います。 サンプル 変数:strFact = "'工場1', 1000, 20/'工場2', 500, 90/'工場3', 2000, 100/'工場4', 900, 10" -------------------JavaScript strFact_WK = <%=strFact %>  ※1 var test = new Array(); var rows = strFact_WK.split("/"); for( var i in rows) { test.push(new Array()); var cols = rows[i].split(","); for( var j in cols) { test[i].push(cols[j]); } } ---------------------- 当然ですが、 ※1の所で strFact_wk = "'工場1', 1000, 20/'工場2', 500, 90/'工場3', 2000, 100/'工場4', 900, 10" とすると作成されます。

専門家に質問してみよう