読者です 読者をやめる 読者になる 読者になる

akiyoko blog

akiyoko の IT技術系ブログです

JavaScript で配列の添え字に文字列やマイナス値を使ったときの挙動

JavaScript での「連想配列」と「配列」の違いは説明するまでもないと思うのですが、それぞれの要素は、

  • 連想配列 の場合は「for ~ in」ループ
  • 配列 の場合は「単純な for 文」ループ

で取り出すというのは、要注意ポイントですよね。

// 一般的な連想配列
console.log("--- (1) 一般的な連想配列 ---");
var obj = {};
obj["a"] = "aaa";
obj["b"] = "bbb";
console.log("obj=", obj);
// 全ての要素を取り出すときは、for-in
for (var i in obj) {
  console.log("obj[" + i + "]=", obj[i]);
}

// 一般的な配列
console.log("--- (2) 一般的な配列 ---");
var arr1 = [];
arr1[0] = "aaa";  // arr1.push("aaa"); でもOK
arr1[1] = "bbb";  // arr1.push("bbb"); でもOK
console.log("arr1=", arr1);
// 全ての要素を取り出すときは、単純なfor文
for (var i = 0; i < arr1.length; i++) {
  console.log("arr1[" + i + "]=", arr1[i]);
}


《 実行結果 》

--- (1) 一般的な連想配列 ---
obj= Object { a="aaa", b="bbb"}
obj[a]= aaa
obj[b]= bbb
--- (2) 一般的な配列 ---
arr1= ["aaa", "bbb"]
arr1[0]= aaa
arr1[1]= bbb


では、ここで問題です。
配列の添え字に文字列やマイナス値を使うとどうなると思いますか?



結論を先に書くと、
配列の要素として認識されず、オブジェクトのプロパティとして認識されるため、全ての要素を取り出すときは「for ~ in」ループ を使う必要が出てくるのです。

// 配列の添え字に文字列を使用した場合は、配列の要素として認識されず、オブジェクトのプロパティとして認識される
console.log("--- (3) 添字に文字列を使用した連想配列 ---");
var arr2 = [];
arr2["a"] = "aaa";
arr2["b"] = "bbb";
console.log("arr2=", arr2);
// for文で取り出すときは、オブジェクトのプロパティとして取得しないといけないので、for-in を使う
// (arr2.length === 0 となるので、単純なfor文では全ての要素は取り出せない)
for (var i in arr2) {
  console.log("arr2[" + i + "]=", arr2[i]);
}

// 配列の添え字にマイナス値を使用した場合も、配列の要素として認識されず、オブジェクトのプロパティとして認識される
console.log("--- (4) 添字にマイナスの値を使用した連想配列 ---");
var arr3 = [];
arr3[0] = "aaa";
arr3[-1] = "bbb";
console.log("arr3=", arr3);
console.log("arr3.hasOwnProperty(-1)=", arr3.hasOwnProperty(-1));
// for文で取り出すときは、オブジェクトのプロパティとして取得しないといけないので、for-in を使う
// (arr3.length === 1 となるので、単純なfor文では全ての要素は取り出せない)
for (var i in arr3) {
  console.log("arr3[" + i + "]=", arr3[i]);
}



FirebugChrome JavaScript コンソールで配列の中身の表示が若干違っているので、どちらものせておきます。


《 実行結果(Firebug) 》

--- (3) 添字に文字列を使用した連想配列 ---
arr2= []
a
	"aaa"
b
	"bbb"
arr2[a]= aaa
arr2[b]= bbb
--- (4) 添字にマイナスの値を使用した連想配列 ---
arr3= ["aaa"]
arr3.hasOwnProperty(-1)= true
arr3[0]= aaa
arr3[-1]= bbb

f:id:akiyoko:20150321022539p:plain

《 実行結果(Chrome JavaScript コンソール) 》

--- (3) 添字に文字列を使用した連想配列 ---
arr2= [a: "aaa", b: "bbb"]
arr2[a]= aaa
arr2[b]= bbb
--- (4) 添字にマイナスの値を使用した連想配列 ---
arr3= ["aaa", -1: "bbb"]
arr3.hasOwnProperty(-1)= true
arr3[0]= aaa
arr3[-1]= bbb

f:id:akiyoko:20150321022555p:plain



ややこしいですね。
特別な理由がないかぎり文字列やマイナス値を添え字として使わない方がベターだと、ちらほら書かれていますので、まあそういうことなのでしょう。


(参考)

インデックスに文字列を使用した場合


仮にインデックスに文字列を使用した場合、それはArrayオブジェクトのプロパティとして認識され、配列の要素とはなりません。


配列 | JavaScript プログラミング解説


JavaScript逆引きレシピ jQuery対応

JavaScript逆引きレシピ jQuery対応