はじめに
研修等でお伝えしていることを書き起こしたような感じなので、色々と変な記述もありますが、大目に見てくださいませmm
最初にまとめを…
JavaScript言語において、for文は繰り返し処理を実現する 「構文」 ですが、forEachは、配列の要素を先頭から最後まで順番に取り出すという 「メソッド(関数)」 です。
同じ「for」という名称が含まれていますし、書き方によっては全く同じ振る舞いをするので、同じ様なものとして混同されやすいですが、全く別もの です。
ちなみに、forEach内の処理を 「中断」 することはできません。
forEachはforと違う書き方くらいだよねと言う感じの理解で最初は構わないのですが、本質的な意味合いの違いを知っていないと、どこかの時点で痛い目に合っちゃいますので、その違いを理解しておくことは重要です。
kintoneの画面
ソースコードの比較
注意事項
学習用のサンプルなので、複雑になることを避けるために、処理中にいきなりreturnを記述していますが、関数内に複数個所のreturnを記述するのはあまり推奨されません。保守性が悪くなりますし、バグの元になりやすいためです。
for文を使った場合
(() => {
'use strict';
kintone.events.on([
'app.record.create.submit',
'app.record.edit.submit',
'app.record.index.edit.submit'
], event => {
const record = event.record;
console.log('処理開始');
for (let i = 0; i < record.一覧.value.length; i++) {
if (record.一覧.value[i].value.行番号.value === record.対象行番号.value) {
record.一覧.value[i].value.内容.value = record.セット文字.value;
console.log(i + '行目:内容を上書きする。');
return event;
}else{
console.log(i + '行目:なにもしない。');
}
}
console.log('処理終了');
return event;
});
})();
18行目のreturnはkintone.events.on()に対する戻り値を返してます。
if文の条件を満たしたときに、kinotne側にeventを戻す処理を行っているため、結果的に処理を中断していることになり、それ以降の処理が実行されません。
forEachを使った場合
(() => {
'use strict';
kintone.events.on([
'app.record.create.submit',
'app.record.edit.submit',
'app.record.index.edit.submit'
], event => {
const record = event.record;
console.log('処理開始');
record.一覧.value.forEach((v, i) => {
if (v.value.行番号.value === record.対象行番号.value) {
v.value.内容.value = record.セット文字.value;
console.log(i + '行目:内容を上書きする。');
return event;
} else {
console.log(i + '行目:なにもしない。');
}
});
console.log('処理終了');
return event;
});
})();
18行目のreturnは、forEachメソッドの第一引数であるcallback関数に対する戻り値を返しています。
JavaScriptの関数内におけるreturnは、そこで関数を終える(抜ける)という意味合いもあるので、その性質を利用し、forEachのcallback関数内でreturnを使うことで、for文におけるcontinueの様な振る舞いをさせることができます。
record.一覧.valueの先頭から最後まで(→テーブルの先頭行から最終行まで)順番に要素を取り出し、callback関数内の処理を行っていく。
if文の条件を満たした時には、「セット文字」を「内容」に代入した後に、(意味合いとしては)処理を中断し次の要素を取り出す処理に移行する。
そして、record.一覧.valueに対する処理を先頭から最後まで実施した後に、24行目が実行されます。
※callback関数は、プログラム的な考え方なので、若干分かりにくいですが、よく出てきますのでぜひ押さえておいていただきたい内容です。
ダウンロードはコチラ
(おまけ)同じ結果でも異なる書き方ができる
console.log('ログ:' + 1);
console.log('ログ:' + 2);
console.log('ログ:' + 3);
console.log('ログ:' + 4);
console.log('ログ:' + 5);
---------------------
for(let i = 0; i < 5; i++){
console.log('ログ:' + (i + 1));
}
---------------------
for(let i = 1; i <= 5; i++){
console.log('ログ:' + i);
}
---------------------
[1, 2, 3, 4, 5].forEach(v => console.log('ログ:' + v));
1つの結果を得るにあたって複数のアプローチがあるので、コードから意図が伝わるか?、可読性や保守性や再利用性などが考慮されているか?等、色々な観点からどのアプローチの仕方が最適なのかを検討する必要があります。
コレでないといけないと言う訳ではなく、(1か月後の自分も含めて)他者がコーディング時の意図について容易に想像でき、誤解が無いように理解できるのかということが重要です。
このあたりは、チームとしての品質を保つためにも重要なポイントになってきます。
【修正箇所】
forEachのcallback関数内でreturnを使うことで、for文における*breakの様な振る舞いをさせることができます。
↓
forEachのcallback関数内でreturnを使うことで、for文におけるcontinueの様な振る舞いをさせることができます。