new Array() や length への代入に、負の数・小数・NaN・大きすぎる数を渡すと出ます。許される範囲、new Array(3) と Array.of(3) の違い、計算結果が NaN になる経路まで確かめます。
配列の長さになれない数を渡すと出ます。
RangeError: Invalid array length
example.js
for (const value of [0, 3, -1, 1.5, NaN, 2 ** 32, 2 ** 32 - 1]) {
try {
console.log(String(value).padEnd(12), '-> length', new Array(value).length);
} catch (error) {
console.log(String(value).padEnd(12), '->', error.name);
}
}
出力書き換えて実行できます
0 -> length 0
3 -> length 3
-1 -> RangeError
1.5 -> RangeError
NaN -> RangeError
4294967296 -> RangeError
4294967295 -> length 4294967295
長さは0以上、2の32乗未満の整数だけです。それ以外は全部これになります。
何が通って、何が落ちるか
example.js
const total = Number('三件');
const size = 2;
console.log(total);
console.log(Math.ceil(total / size));
出力書き換えて実行できます
NaN
NaN
javascript
const count = Number('三件');
new Array(count);
RangeError: Invalid array length
- 負の数 … 落ちる
- 小数 … 落ちる(
1.5 は整数ではない)
NaN … 落ちる
- 2の32乗ちょうど … 落ちる。1つ手前までが上限
原因1: 計算結果が NaN になっている
実務でいちばん多い形です。
example.js
function makeSlots(count) {
if (!Number.isInteger(count) || count < 0) {
throw new RangeError(`件数が数値ではありません: ${count}`);
}
return new Array(count).fill(null);
}
console.log(makeSlots(3));
try {
makeSlots(Number('三件'));
} catch (error) {
console.log(error.name + ': ' + error.message);
}
出力書き換えて実行できます
[ null, null, null ]
RangeError: 件数が数値ではありません: NaN
example.js
const total = 3;
const shown = 5;
console.log(total - shown);
出力書き換えて実行できます
-2
Number() が NaN を返し、そのまま長さに使われています。
example.js
const total = 3;
const shown = 5;
console.log(new Array(Math.max(0, total - shown)).length);
出力書き換えて実行できます
0
example.js
const list = [1, 2, 3];
try {
list.length = -1;
} catch (error) {
console.log(error.name + ': ' + error.message);
}
list.length = 1;
console.log(list);
出力書き換えて実行できます
RangeError: Invalid array length
[ 1 ]
落ちた場所ではなく、NaN が生まれた場所を探してください。
→ 文字列を数値に変換する
NaN かどうかは Number.isNaN() で確かめます。
example.js
console.log(new Array(3));
console.log(new Array(3).length);
console.log(Array.of(3));
console.log(new Array(3, 4));
出力書き換えて実行できます
[ <3 empty items> ]
3
[ 3 ]
[ 3, 4 ]
example.js
console.log(new Array(3).map((_, i) => i));
console.log(Array.from({ length: 3 }, (_, i) => i));
console.log(new Array(3).fill(0));
出力書き換えて実行できます
[ <3 empty items> ]
[ 0, 1, 2 ]
[ 0, 0, 0 ]
自分で投げるほうが、原因がその場で分かります。
原因2: 引き算で負になった
「残りの数だけ枠を作る」ような計算で、表示済みが総数を超えると負になります。
Math.max(0, ...) で床を作ってください。
原因3: length に代入した
length への代入は切り詰めとして働きます。負の数は入れられません。
空にしたいなら list.length = 0 です。
ただし、同じ配列を指している変数がすべて影響を受けます。新しい配列を作るほうが安全なことも多くあります。
new Array(3) と Array.of(3) は別物
ここも取り違えやすいところです。
- 数を1つだけ渡す → 長さの指定
- 2つ以上渡す → 要素として並ぶ
Array.of() → いつでも要素
new Array(3) が作るのは穴が3つ並んだ配列です。
map() を通しても何も起きません。
連番を作るなら Array.from()、同じ値で埋めるなら fill() です。
→ 配列の基本
似ているエラーとの違い
| 文言 |
意味 |
Invalid array length |
長さになれない数を渡した |
Cannot read properties of undefined |
範囲の外を読んだあとの中身 |
x is not a function |
Array を関数でないものと取り違えた |
Maximum call stack size exceeded |
再帰が止まらない |
このページの実行結果は Node 22.22.3 のものです。文言は処理系と版によって変わります。
探しかたの順序
new Array() か length = に渡している値を、そのまま出す
NaN なら → 数値変換まで遡る(Number() / parseInt() / 割り算)
- 負の数なら → 引き算に
Math.max(0, ...) を入れる
- 小数なら →
Math.ceil() / Math.floor() で整数にする
まとめ
- 長さは0以上・2の32乗未満の整数だけ
- いちばん多い原因は
NaN。 数値変換の失敗が伝わってきている
- 引き算で負になる経路には
Math.max(0, ...)
length への代入は切り詰め。負の数は入れられない
new Array(3) は穴3つ、Array.of(3) は要素1つ
- 連番は
Array.from()、埋めるなら fill()