すごく好きなプログラム関数は?と聞かれた時に「配列操作」というぐらい好きなのですが、理由としては、用意した箱の中身を出し入れしてそれらを合計して計算したり、簡単なデータベースを構築するのが、たまらなくプログラミングしている気分になりますね。
そんな配列操作をしている時に、配列のkeyに数字を使った場合、javascriptで無意味な配列が作られてしまい、ループ分で不具合が発生する可能性があったので、忘れないように、少し深く調査しておこうと思います。
尚、プログラムの配列操作を知らない人は、リファレンスページなどでご確認いただいてから、見ないと意味が分かりませんのでご了承ください。
また、こうした状況をキチンと理解しているベテランプログラマの方は、「そんな事知っとるわい」と考えずに、もっと詳しく知っていることを僕まで教えてください。
Javascript
javascriptのスニペット実行結果の確認は、コンソールなどに貼り付けると簡単に行えます。
var arr = [];
arr[10] = "test";
console.log(arr.length);
> 11
arrのkeyに数値の"10"を入れているので、配列の10番目に値を入れている状態になります。
合計11個の配列データが作られてしいますので、データを1つしか登録していないと勘違いしないようにしましょう。
var arr = [];
arr["test"] = "test";
console.log(arr.length);
> 0
arrは文字列をkeyに使うことにより、通常の配列ではなく、連想配列扱いになった為に、length属性が無くなってしまいました。
これ自体はさほど不思議ではないのですが、数値を入れた配列のkeyに文字列を入れるとどうなるのでしょう?
var arr = [];
arr[10] = "test";
arr["test"] = "test";
console.log(arr.length);
> 11
結果は、数値の部分だけがlength属性で繁栄されています。
そして、console.log(arr["test"])を実行すると、ちゃんと代入した値が返ってきます。
これはJavascriptが配列も連想配列も"object"という型になっている為に混合している状態も受け入れているんでしょうね。
でも、今後の言語のバージョンアップでBANされる可能性もあるので、なるべくなら混合使用は辞めたほうがいいかもしれませんね。
var arr = [];
arr[10] = "test";
arr["test"] = "test";
console.log(Object.keys(arr));
> (2) ["10", "test"]
しかし、lengthに頼らなくても、"Object.keys"で取得すると、正常な状態は取れますね。
for文を使う時のお作法でlengthを使う人も多いと思いますが、配列をarrayとするかobjectとするかで、keyのとり方も変わってくる事を理解しなければいけませんね。
当たり前ですが、こうした点でバグが発生する事も少なくないでしょう。
Objectを意識した配列
Javascripthは配列も連想配列も"object"という型になってしまう事が分かりましたが、数値を使う時も下記のようにすると、数値keyでもarrayではなくobjectにしてくれます。
var arr = {};
arr[10] = "test";
console.log(arr.length);
console.log(Object.keys(arr));
> undefined
> ["10"]
"var arr = [];"を"var arr = {};"と下だけなんですが、配列では無いため、length属性はありません。
でも、"Object.keys"では、ちゃんとkey情報が取得できます。
どうしてもlengthが欲しい場合は、下記のように書くといいでしょう。
var arr = {};
arr[10] = "test";
console.log(Object.keys(arr).length);
> 1
ちなみに、配列のkeyに変数を利用して代入する時に、keyの変数の型を数値と文字列に違いがあるのか検証してみましょう。
var a = 10;
var arr1 = [];
arr1[a] = "test-1";
console.log(arr1.length);
var b = "10";
var arr2 = [];
arr2[b] = "test-2";
console.log(arr2.length);
var c = "test";
var arr3 = [];
arr3[c] = "test-3";
console.log(arr3.length);
> 11
> 11
> 0
予想通り、数値を文字列で登録したところで、数値扱いされてしまいますね。
javascriptの良いところでもあり、型が曖昧なため、厳密にプログラムしようとすると、少し不便に感じる所でもあります。
でも、こうした特性をちゃんと理解してコーディングするようにしましょう。
javascriptリファレンスページ
MDN Web Doc
超基本が書かれているので、初心者の方は是非読んでおきましょう。
JS Studio
今回書いた前半の説明が細かくされています。
とほほのJavascriptリファレンス
老舗のプログラムリファレンスサイトです。
0 件のコメント:
コメントを投稿