JavaScript配列の反復に「for…in」ループを使うのはなぜ悪い考えなのか?
for...inループの問題点とは
JavaScriptで配列を反復処理する場合、多くの場面では「for...in」ループよりも通常の「for」ループを使用する方が適切です。その理由は、「for...in」ループは配列のインデックス(キー)を返す仕様になっており、途中に存在する「空きインデックス(ホール)」については一切考慮されないためです。
一方、通常の「for」ループは配列の値を順番に取り出し、空きインデックスには「undefined」が返されます。そのため、配列の構造を正確に把握しながらコードを書くことができ、開発者の混乱を防げます。
構文1:for...inループ
for (var x in array) {
// コード
};上記が「for...in」ループの基本構文です。
構文2:通常のforループ
for () {
// コード
};上記が通常の「for」ループの基本構文です。
例1:for...inループの動作
次の例では、最初に配列「num」には5つの要素(インデックス0〜4)しか格納されていません。その後、インデックス4から離れた位置にあるインデックス7に値を追加すると、「for...in」ループは空きインデックス(5と6)の存在を通知することなく、存在するインデックスのみを連続的に処理します。通常の「for」ループではこのような挙動にはなりません。この違いは開発者を混乱させる原因となります。
<html>
<body>
<script>
var num = [1,2,3,4,5];
num[7] = 7;
for (var x in num) {
document.write(x);
document.write("</br>");
}
</script>
</body>
</html>
出力結果
0
1
2
3
4
7
例2:通常のforループの動作
次の例では、「for...in」ループとは異なり、通常の「for」ループではインデックスではなく値が表示されます。さらに、空きインデックスには「undefined」が出力されるため、配列に抜けがあることが明確になり、開発者が混乱することはありません。
<html>
<body>
<script>
var num = [1,2,3,4,5];
num[7] = 7;
for (var i = 0; i < num.length; i++) {
document.write(num[i]);
document.write("</br>");
}
</script>
</body>
</html>
出力結果
1
2
3
4
5
undefined
undefined
7
まとめ
このように、「for...in」ループは配列の疎な部分(ホール)を無視してしまうため、配列の反復処理には通常の「for」ループのほか、ES6で導入された「for...of」ループやforEach()メソッドを使用するのが推奨されます。そもそも「for...in」ループはオブジェクトのプロパティ列挙を目的とした構文であり、プロトタイプチェーン上のプロパティまで列挙してしまう可能性がある点にも注意が必要です。
-
JavaScriptのオブジェクト配列に配列メソッドを適用する方法
JavaScriptでは、オブジェクトが格納された配列に対しても、通常の配列と同じようにpop()、push()、splice()などの標準的な配列メソッドをそのまま使用できます。オブジェクト配列はあくまで「配列」であるため、要素としてオブジェクトが入っていても配列操作のAPIは共通で動作します。 コード例 以下は、JavaScriptオブジェクトの配列に対して配列メソッドを使用するサンプルコードです。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8
-
JavaScriptのforループを使って空のオブジェクトにプロパティを設定する方法
JavaScriptでは、for...inループを使うことで、既存のオブジェクトから空のオブジェクトへプロパティを簡単にコピーできます。以下に、forループを使用して空のオブジェクトにプロパティを設定するサンプルコードを紹介します。 コード例 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width,