配列の範囲外アクセスがエラーにならずundefinedになる
JavaScriptの配列は範囲外の添字にアクセスしてもエラーを投げません。静かにundefinedを返すため、Java・Python・C#のように例外で気づくことができません。
なぜエラーが出ないのか
出力: undefined
(エラーなし)- JavaScriptは何も報告しません。文法として正しいためです
出力: undefined- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 const nums = [10, 20, 30]; 2 console.log(nums[5]); ^
3個の配列に添字5の要素はありません。JavaScriptは範囲外アクセスを例外にせず、静かにundefinedを返します。
直し方: 5 を 1 にします。
パターン2
1 const nums = [10, 20, 30]; 2 console.log(nums[-1]); ^
Pythonと違い、JavaScriptの配列は負のインデックスを末尾からの参照として扱いません。nums[-1]は存在しないプロパティを読むのと同じ扱いになり、undefinedになります。
直し方: -1 を 2 にします。
パターン3
1 const nums = [10, 20, 30]; 2 const lastIndex = nums.length ; ^ 3 console.log(nums[lastIndex]);
lengthは要素数(3)で、最後の添字はそれより1小さい2です。lengthをそのまま添字に使うと1つ先の存在しない要素を指してしまいます。
直し方: (空) を - 1 にします。
パターン4
1 const letters = ["a", "b", "c"]; 2 console.log(letters[10]); ^
要素数3の配列に添字10はありません。範囲外でも例外にはならず、静かにundefinedが返ります。
直し方: 10 を 0 にします。
パターン5
1 const grid = [[1, 2], [3, 4]]; 2 console.log(grid[1][5]); ^
2次元配列でも規則は同じです。内側の配列も要素数を超えた添字はundefinedになります。
直し方: 5 を 0 にします。
よくある誤解
他言語の経験から「範囲外アクセスは例外で止まるはず」と思い込むと、JavaScriptではその前提が崩れます。エラーが出ない以上、出力を目で確認するかコードを読むまで気づけません。
実務での勘所
この挙動の背景には、JavaScriptの配列が実は特殊な形をしたオブジェクトである、という実装上の事実があります。arr[10]という読み取りは、内部的には"10"という文字列のプロパティを持つオブジェクトからその値を探しているだけで、見つからなければ(存在しないプロパティを読んだときと同じ扱いで)undefinedを返します。Javaのような、あらかじめ固定長のメモリ領域を確保する配列とは実装が根本的に異なるため、「範囲外」という概念自体がエンジンの内部には存在しません。
関連するエラー
- undefinedのプロパティ読み取りエラーの原因undefinedになった値のプロパティやメソッドにアクセスしようとしたときに出る、JavaScript学習者が最も多く遭遇するエラーです。
- == が意図しない型変換で真になってしまう(===との違い)==は比較の前に両辺の型をそろえようとするため、文字列の"0"や空文字列、falseなどが数値の0と等しいと判定されてしまいます。