8月20日、フロントエンドエンジニア向けの海外メディアCSS Tricksが「All About JavaScript Loops」と題した記事を公開し、話題を博している。この記事では、JavaScriptにおける様々なループの種類と、それぞれの使用方法およびメリット・デメリットについて詳しく解説されている。以下に、その内容を紹介する。
JavaScriptには、様々な種類のループが存在し、それぞれ異なる状況に適した使い方がある。ループを選択する際には、コードの可読性やパフォーマンス、使いやすさなど、さまざまな要因を考慮する必要がある。
while
ループとdo...while
ループ
while
ループは、特定の条件が満たされるまで処理を繰り返す基本的なループである。条件が最初にチェックされるため、条件が満たされない場合には一度も実行されないことが特徴だ。while
ループは、そのシンプルさから、多くのケースで最速で最も読みやすい選択肢となる。しかし、条件が常に真の場合、無限ループに陥るリスクがある点に注意が必要だ。
一方、do...while
ループは、条件が最後にチェックされるため、少なくとも一度はループ内の処理が実行されるという特徴がある。この違いにより、do...while
ループは、少なくとも一度実行したい処理がある場合に適しているが、使用頻度は比較的低い。
let queue1 = ["a", "b", "c"];
while (queue1.length) {
let item = queue1.shift();
console.log(item);
}
let queue2 = [];
do {
let item = queue2.shift() ?? "empty";
console.log(item);
} while (queue2.length);
for
ループ
for
ループは、特定の回数だけ操作を繰り返す場合に使用される。例えば、数値の範囲を反復処理する場合に最適だ。このループは、特に初心者には少し取っつきにくいかもしれないが、そのシンタックスを覚えることで、コードの意図が明確になり、誤解を防ぐことができる。
for
ループは、操作の繰り返し回数が事前に分かっている場合に最適であり、通常のループ処理で最も一般的に使用される。しかし、構文が少し複雑であるため、特定の状況下ではwhile
ループや他のループが好まれることもある。
for (let i = 1; i <= 5; i++) {
console.log(i);
}
for...of
ループとfor await...of
ループ
for...of
ループは、配列や文字列などの反復可能なオブジェクトを簡単にループ処理するための便利な方法である。特に配列の各要素を処理する際に使いやすく、コードが読みやすくなる。
for...of
ループは、反復可能なオブジェクト全般に対応しているため、配列だけでなく、セットやマップ、さらにはカスタムイテラブルも処理できる。これにより、柔軟性が高く、多くの場面で役立つ。しかし、パフォーマンスを最優先する場合や、細かい制御が必要な場合には、他のループが適していることもある。
非同期処理を行う場合には、for await...of
ループが使用される。このループは、非同期の反復可能なオブジェクトを処理するために設計されており、async
関数と組み合わせて使用することで、非同期処理の結果を逐次取得できる。
let myList = ["a", "b", "c"];
for (let item of myList) {
console.log(item);
}
// 非同期処理の例
async function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function* aNumberAMinute() {
let i = 0;
while (true) {
yield i++;
await delay(60000);
}
}
for await (let i of aNumberAMinute()) {
console.log(i);
if (i >= 59) {
break;
}
}
forEach
とmap
ループ
forEach
とmap
は、ループそのものではないが、リストを反復処理するためのメソッドであり、多くの場面で使用される。forEach
は、配列の各要素に対して関数を実行するための方法で、インデックスも取得できるため、特定の要素を処理する際に便利だ。しかし、forEach
は歴史的にfor
ループよりもパフォーマンスが劣るとされており、大規模なデータセットを処理する場合には注意が必要である。
map
は、配列の要素を変換して新しい配列を生成するための方法である。コードの可読性が高くなるが、forEach
同様、パフォーマンス面での考慮が必要だ。また、Reactのようなライブラリでは、map
が頻繁に使用され、JSX内で要素をリスト表示する際に便利である。
let myList = ["a", "b", "c"];
myList.forEach((item, index) => {
console.log(`${index}: ${item}`);
});
function MyList({items}) {
return (
<ul>
{items.map((item) => {
return <li>{item}</li>;
})}
</ul>
);
}
for...in
ループ
for...in
ループは、オブジェクトのキーを反復処理するための方法である。このループは、オブジェクトのすべての列挙可能なプロパティにアクセスするが、プロトタイプチェーン上のプロパティにもアクセスするため、予期しない動作が発生する可能性がある。そのため、for...in
ループは使用する際に慎重さが求められるが、キーの順序が一貫している現在のブラウザ環境では、特定のユースケースにおいて有用である。
let myObject = {
a: 1,
b: 2,
c: 3,
};
for (let k in myObject) {
console.log(myObject[k]);
}
詳細はAll About JavaScript Loopsを参照していただきたい。