問題
突然ですが以下のlengthの値ってどうなると思いますか?
const array = [];
array['book'] = 'santai';
console.log(array); // [ age: 'santai']
console.log(array.length); // …?
ぜひ、ちょっと考えてみてください。
答えは0です。
筆者はundefinedだと思ったのですがJavaScriptの仕様では0になるようです。他にも1になるのではと考えた人もいるんじゃないでしょうか?
最初から処理を追って行ってみましょう。
まずJavaScriptでは配列にプロパティを追加することができてしまうみたいです。
array['book'] = 'santai';
console.log(array); // [ age: 'santai']
この時点で配列は連想配列に変化すると思っていたのですが、どうやら配列のままのようです。
console.log(Array.isArray(array)); // true
もしも配列が連想配列に変化していたのなら、lengthプロパティを呼び出すとundefinedが返ってくるはずです。
const obj = {};
console.log(obj.length); // undefined
配列のままなので正常にlengthプロパティを呼び出すことができ、答えは1になる……と思いきや帰ってきたのは0。
console.log(array.length); // 0
どうやらlengthは配列内に数値以外のキーがあった場合、それを検知できないみたいです。
const array = [];
array['book'] = 'santai';
array.push(1)
console.log(array); // [ 1, book: 'santai' ]
console.log(array.length); // 1
MDNを漁ってみたのですがこのような仕様について記述してある項目は見つからず……。どなたか詳しく書いてある文献をご存知でしたら教えてくださいませ<(_ _)>
解決策
解決策としてはObject.keys()
を使えば期待するような結果が得られます。
const array = [];
array['book'] = 'santai';
console.log(array); // [ age: 'santai']
console.log(Object.keys(array).length); // 1
const array = [];
array['book'] = 'santai';
array.push(1)
console.log(array); // [ 1, book: 'santai' ]
console.log(Object.keys(array)); // [ '0', 'book' ]
console.log(array.length); // 2
追記(2021/04/29)
@htsign さんがこの現象について腑に落ちる説明をしてくださいました。
@lhankor_mhy さんが他の例を紹介してくださいました。
ぜひコメントにも目を通して頂ければと思います。
参考