オブジェクトのキーは数値でも文字列に変換される(1と"1"は同じキー)
JavaScriptのオブジェクトのプロパティキーは、Symbolを除きすべて文字列として扱われます。数値のキーを指定しても内部的には文字列に変換されるため、数値の1と文字列の"1"は同じキーとして衝突します。
なぜエラーが出ないのか
出力: 1
(エラーなし)- JavaScriptは何も報告しません。文法として正しいためです
出力: 1- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 const votes = {}; 2 votes[1] = "apple"; 3 votes["1"] = "banana"; ^ 4 console.log(Object.keys(votes).length);
出力: 1期待: 2 (エラーにはなりません)
votes["1"]はvotes[1]と同じキーを指します。別々の投票のつもりで書いても、片方がもう片方を上書きしてキーは1つのままです。
直し方: "1" を 2 にします。
広告
広告スロット(未設定)
パターン2
1 const cache = {}; 2 cache[10] = "x"; 3 cache["10"] = "y"; ^ 4 console.log(Object.keys(cache).length);
出力: 1期待: 2 (エラーにはなりません)
cache["10"]はcache[10]と同じキーになります。数値と文字列のキーは区別されません。
直し方: "10" を 20 にします。
パターン3
1 const inventory = {}; 2 inventory[100] = "sword"; 3 inventory["100"] = "shield"; ^ 4 console.log(Object.keys(inventory).length);
出力: 1期待: 2 (エラーにはなりません)
inventory["100"]はinventory[100]と同一のキーとして扱われ、上書きされてキーは1つのままになります。
直し方: "100" を 200 にします。
よくある誤解
「数値のキーと文字列のキーは別物として区別されるはず」という思い込みは誤りです。obj[1]とobj["1"]は同じプロパティを指すため、片方への代入がもう片方の値を上書きします。
まとめ
オブジェクトのキーは数値でも文字列に変換される(1と"1"は同じキー)は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。