はじめに
Vue.jsを学習中のエンジニアです👩🏻💻
現在、予約管理システムを開発中なのですが、コードを見直していると forEach メソッドを多用していることに気づきました。上司からのPR(プルリクエスト)レビューにも 「forEach 以外の書き方を覚えよう」 とコメントをいただいたほどです😅
当時はなぜforEachメソッドの多用が推奨されないのか、あまり理解できていませんでした。
そこで、forEachについての理解を深め、自分自身のアウトプットとしてこの記事を書こうと思います!
■forEachメソッドを多用することが良くないとされる理由
副作用の可能性
forEach
は、各要素に対して指定された関数を実行しますが、その関数内で副作用が発生する可能性があります。副作用とは、関数が外部の状態を変更することです。副作用が多いコードはバグを引き起こしやすく、テストやデバッグが難しくなります。
let total = 0;
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(num => {
total += num;
});
console.log(total); // 出力: 15
この例では、forEach内でtotalが変更されます。
totalの変更はforEach内で行われているため、コードを読む人はtotalの値がどのように変わるのかを理解するために、forEachの内部を追う必要があります。
非同期処理に不向き
forEach は同期的に動作するため、非同期処理を必要とする場合には適していません。forEach 内で非同期処理を実行すると、全体の処理が完了する前に次のステップに進んでしまうことがあります。
const fetchData = async (url) => {
const response = await fetch(url);
return response.json();
};
const urls = ['url1', 'url2', 'url3'];
urls.forEach(async (url) => {
const data = await fetchData(url);
console.log(data);
});
この例では、forEach 内で async/await を使用していますが、非同期操作の完了を待たずに次の url に進んでしまいます。
戻り値がない
forEach メソッドは戻り値を持たないため、処理の結果を配列として取得することができません。そのため、結果をどこかに保存する必要があります。コードを読んでいる人は、forEach の内部でどのような操作が行われているかを逐一追いかけなければならず、これは可読性を低下させる一因となります。
読みやすさとメンテナンス性
コードの意図を明確にするためには、適切な高階関数を使用することが重要です。例えば、配列の要素を変換したい場合は map
、フィルタリングしたい場合は filter
を使う方が読みやすく、メンテナンスしやすいコードになります。
以下のコード例を比較してみます。
forEach
の例
const numbers = [1, 2, 3, 4, 5];
const doubled = [];
numbers.forEach(num => {
doubled.push(num * 2);
});
console.log(doubled);
map
の例
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled);
forEach
を使用した例では、doubled
配列を外部で宣言し、forEach
内で値をプッシュする必要がありますが、map
を使用する例では、より簡潔で読みやすいコードになります。
まとめ
ここまでお読みいただき、ありがとうございます🙇🏻♀️
forEach
を多用することがダメなわけではなく、コードを書く際に、実行する処理に適したメソッドを選択できることが重要であると学びました。
次回の開発では、様々なメソッドを適切に使用することを意識して取り組んでいきたいと思います!