JavaScript 配列の length の基本
配列の「大きさ」を調べるときは、配列.length を使います。ここでいう「大きさ」は、最後の要素の位置(インデックス)+1の値です。初心者がつまずきやすいポイントは「length = 実際の要素数」とは限らないこと。例題で丁寧に見ていきましょう。
配列とインデックスの関係
- インデックスの始まり: 配列の最初の位置は 0(ゼロ)。3つ要素があればインデックスは 0, 1, 2。
- length の意味: 「最後のインデックス + 1」。要素が3つなら
lengthは 3。
const nums = [10, 42, 52];
console.log(nums[0]); // 10
console.log(nums[1]); // 42
console.log(nums[2]); // 52
console.log(nums.length); // 3
JavaScript- ポイント: 実際の「要素数」は通常は
lengthと一致しますが、空の箇所がある場合はズレます。
スカスカ配列と length のズレ
- スカスカ配列とは: 途中のインデックスに値が入っていない配列。JavaScriptではこれが作れてしまいます。
- length は大きめに出る: 最後に値を入れた位置で
lengthが決まるため、実際の「中身がある数」と異なることがある。
const data = [];
data[0] = 10;
data[5] = 35;
console.log(data); // [10, <empty>, <empty>, <empty>, <empty>, 35]
console.log(data.length); // 6 ← 最後のインデックス 5 + 1
// 実際に「値が入っている要素」は 2 個(0 と 5)だけ
JavaScript- 初心者の落とし穴:
lengthを「中身の数」と思ってループすると、空の場所も回ってしまい、undefinedを処理してバグにつながることがあります。
length を書き換えると何が起きる?
- 増やすと空の要素が増える: 大きな値を代入すると、末尾に空の場所が増える(中身は入らない)。
- 減らすと要素が消える: 小さくすると末尾から要素が削除される(破壊的操作)。
const arr = [10, 42, 52];
arr.length = 5;
console.log(arr); // [10, 42, 52, <empty>, <empty>]
arr.length = 2;
console.log(arr); // [10, 42] ← 52 は削除された
JavaScript- 注意点:
lengthを小さくする操作は元に戻せません(消えた値は復活しない)。
例題で身につける
例題1:配列の末尾に要素を追加して、正しく長さを確認する
- 狙い: 普通の配列なら
lengthは要素数と一致することを確認。
const fruits = ["apple", "banana"];
fruits.push("orange");
console.log(fruits.length); // 3
JavaScript- ポイント:
pushは空の箇所を作らず、末尾に要素を追加する安全な方法。
例題2:穴あき配列をループで処理する時の落とし穴
- 狙い:
forでlengthを使うだけでは空の要素に当たることがある。
const data = [];
data[0] = "A";
data[3] = "D";
for (let i = 0; i < data.length; i++) {
console.log(i, data[i]);
}
// 出力:
// 0 A
// 1 undefined
// 2 undefined
// 3 D
JavaScript- 回避策: 空を飛ばしたいなら「存在チェック」を入れる。
for (let i = 0; i < data.length; i++) {
if (i in data) { // その位置に要素があるかチェック
console.log(i, data[i]);
}
}
// 出力:
// 0 A
// 3 D
JavaScript例題3:実際の「要素が入っている数」を数える
- 狙い: スカスカ配列で「実値の個数」を数える方法。
const arr = [];
arr[1] = "B";
arr[4] = "E";
arr[7] = "H";
let count = 0;
for (let i = 0; i < arr.length; i++) {
if (i in arr) count++;
}
console.log(count); // 3
JavaScript- 別解:
filterを使うとすっきり。ただし空要素はフィルタ対象外なので、undefinedを入れていた場合は注意。
const arr2 = [undefined, "X", undefined, "Y"];
// スカスカではない「undefined」の要素は存在しているため、filterの条件次第で扱いが変わる
const filled = arr2.filter((v, i) => i in arr2);
console.log(filled.length); // 4(全部存在している)
// 「値が定義されている数」を知りたいなら
const definedCount = arr2.filter(v => v !== undefined).length;
console.log(definedCount); // 2
JavaScript例題4:length を使って配列をリセットする
- 狙い: 中身を空にしたいときの簡単テクニック。
let cache = ["tmp1", "tmp2", "tmp3"];
cache.length = 0; // 全消し
console.log(cache); // []
JavaScript- ポイント: 参照を共有している他の変数にも影響する場合があるので、共有状態には注意。
実践で役立つコツ
- 安全な追加・削除: 追加は
push、削除はpop(末尾)やshift(先頭)、途中はspliceを使う。 - 穴あき配列にしない:
arr[5] = ...のような飛び番号で代入しない。pushやspliceを使って連続した配列を保つ。 - ループ時の存在チェック: スカスカの可能性があるなら
if (i in arr)やArray.prototype.hasOwnProperty.call(arr, i)を入れる。 - 要素の「定義済み」判定: 値の有無を知りたいときは
v !== undefinedかv != nullを使い分ける(nullも空扱いしたいなら後者)。
まとめ
- 基本:
lengthは「最後のインデックス + 1」。通常は要素数と一致する。 - 例外: 穴あき(スカスカ)配列だと「中身の数」と一致しない。
- 操作:
lengthは書き換え可能。増やすと空が増え、減らすと末尾が消える。 - 実務的コツ: 穴あき配列は避け、
push/pop/spliceを使う。ループでは存在チェックを入れる。
