JavaScriptの質問です。


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

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

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

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2011/03/09 15:54:18
  • 終了:2011/03/09 16:33:18

ベストアンサー

id:y-kawaz No.3

y-kawaz回答回数1420ベストアンサー獲得回数2252011/03/09 16:25:45

ポイント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

imo758回答回数121ベストアンサー獲得回数192011/03/09 16:01:24

ポイント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

Galapagos回答回数963ベストアンサー獲得回数892011/03/09 16:04:37

ポイント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

y-kawaz回答回数1420ベストアンサー獲得回数2252011/03/09 16:25:45ここでベストアンサー

ポイント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の間違いですので直して使ってください(^^;

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません