JavaScriptの質問です。


────────────────────
var hoge = [];
hoge['a'] = ['b'];

alert(hoge.length + " : " + hoge['a']);
────────────────────
上記のようなスクリプトを走らせた場合、アラート文として表示される結果は
────────────────────
0 : b
────────────────────
になります。

hoge['a']の中身が "b" という結果が確かに返ってきているので、配列hogeの中には一件の値が入っているはずです。
なのに、hoge.lengthが 0 とされてしまうのは、なぜでしょうか?

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/03/09 16:33:18
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:y-kawaz No.3

回答回数1422ベストアンサー獲得回数226

ポイント36pt

配列(Array)では数字のインデックスしか使えません。

数字以外のインデックスへのアクセスは、そのオブジェクトのプロパティへのアクセスとして扱われます。

で、配列のlengthプロパティはあくまで配列のサイズを返すものであり、オブジェクト自身のプロパティの数を返すわけではないのでゼロになります。

ちょっと分かりにくいかもしれませんが、配列もオブジェクトなのでこのようなことができてしまいます。


オブジェクトのプロパティの数を数えたいなら、例えば以下のようにすれば数えられます。

function countProperty(obj) {
  var count = 0;
  for(var p in hoge) {
    if(hoge.hasOwnProperty(p)) {
      count++;
    }
  }
  return count;
}

var hoge = [];
hoge.a = 'b';               // hoge['a'] = 'b' と同じ
alert(hoge.a);              // bが表示される
alert(hoge.length);         // 0が表示される
alert(countProperty(hoge)); // 1が表示される

hoge.push('c')
alert(hoge[0]);             // cが表示される
alert(hoge.length);         // 1が表示される
alert(countProperty(hoge)); // 2が表示される(0と"a"で2つ)
id:nacbox
 hoge.a = 'b';               // hoge['a'] = 'b' と同じ

おおお……。

なるほど、目の前の靄が晴れた気分です。


結局、数を数えようと思ったら、for~inでぐるぐる回すしかなさそうですね。

カウントする部分を関数化してしまうのは、イタダキです。


だいたい疑問点は解消できました。

ありがとうございました!

2011/03/09 16:32:05

その他の回答3件)

id:imo758 No.1

回答回数121ベストアンサー獲得回数19

ポイント36pt

JavaScriptの配列をも〜っと深く理解する:lengthの不思議な動作

http://builder.japan.zdnet.com/script/sp_javascript-kickstart-20...

が参考になるのではないでしょうか

id:nacbox

でぇぇぇ!!

完全に予想外の答え……。


てことは……

てことは……

件数を数えようと思ったら、for~inでぐるぐる回してカウントするしかないということ??

2011/03/09 16:14:34
id:Galapagos No.2

回答回数963ベストアンサー獲得回数89

ポイント10pt

それは、hoge が配列として宣言されていないからです。


hoge を配列として扱うためには、以下のようにします。

ここでは要素数5の配列として宣言してみます。

var hoge = new Array(5);
hoge['a'] = ['b'];

alert(hoge.length + " : " + hoge['a']);
id:nacbox

上記だと、確かに件数は5件と出ます。

ですがこの場合は、初めから件数が分かってるという前提ですよね。

たとえば、hoge.push()でどんどん配列に値が追加されるような場合

(そしてその格納される値の大きさが、連番などではなく大きな数字の場合)、

imo758さんの回答されたURL先の情報にならうと、

lengthの値は件数と同一ではなくなってしまうのではないのでしょうか。

2011/03/09 16:21:13
id:y-kawaz No.3

回答回数1422ベストアンサー獲得回数226ここでベストアンサー

ポイント36pt

配列(Array)では数字のインデックスしか使えません。

数字以外のインデックスへのアクセスは、そのオブジェクトのプロパティへのアクセスとして扱われます。

で、配列のlengthプロパティはあくまで配列のサイズを返すものであり、オブジェクト自身のプロパティの数を返すわけではないのでゼロになります。

ちょっと分かりにくいかもしれませんが、配列もオブジェクトなのでこのようなことができてしまいます。


オブジェクトのプロパティの数を数えたいなら、例えば以下のようにすれば数えられます。

function countProperty(obj) {
  var count = 0;
  for(var p in hoge) {
    if(hoge.hasOwnProperty(p)) {
      count++;
    }
  }
  return count;
}

var hoge = [];
hoge.a = 'b';               // hoge['a'] = 'b' と同じ
alert(hoge.a);              // bが表示される
alert(hoge.length);         // 0が表示される
alert(countProperty(hoge)); // 1が表示される

hoge.push('c')
alert(hoge[0]);             // cが表示される
alert(hoge.length);         // 1が表示される
alert(countProperty(hoge)); // 2が表示される(0と"a"で2つ)
id:nacbox
 hoge.a = 'b';               // hoge['a'] = 'b' と同じ

おおお……。

なるほど、目の前の靄が晴れた気分です。


結局、数を数えようと思ったら、for~inでぐるぐる回すしかなさそうですね。

カウントする部分を関数化してしまうのは、イタダキです。


だいたい疑問点は解消できました。

ありがとうございました!

2011/03/09 16:32:05

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 <textarea> 1 0 0 2011-03-09 16:04:13
  • id:y-kawaz
    あ、すみません。
    countProperty関数の中の↓この部分、

    for(var p in hoge) {

    hogeじゃなくてobjの間違いですので直して使ってください(^^;

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません