🙄
【JavaScript】Array.lengthの不可解な挙動
問題
突然ですが以下のlength
の値ってどうなると思いますか?
const array = [];
array['book'] = 'santai';
console.log(array); // [ book: 'santai']
console.log(array.length); // …?
ぜひ、ちょっと考えてみてください。
答えは0です。
console.log(array.length); // 0
筆者はundefined
だと思ったのですがJavaScriptの仕様では0になるようです。他にも1になるのではと考えた人もいるんじゃないでしょうか?
最初から処理を追って行ってみましょう。
まずJavaScriptでは配列にプロパティを追加することができてしまうみたいです。
array['book'] = 'santai';
console.log(array); // [ book: 'santai']
この時点で配列は連想配列に変化すると思っていたのですが、どうやら配列のままのようです。
console.log(Array.isArray(array)); // true
配列のままなので正常に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); // [ book: '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
参考
Discussion
仕様書では条件が定義されているけれど、実装は定義されていないようです。
つまり、JavaScriptエンジンが違えば、原理的に異なる動作を実装することができると思います。