はじめに
JavaScriptを書いており、配列のループをしようとして弄ばれたときのメモ&ネタ話です。
内容
やりたいこと
最近JavaScriptを業務で使う中で、
配列を処理して配列内の値がtrueならエラーにしたい!
ということがあったので、JavaScriptのループ処理についてググることがあった。
やったこと
自分の普段のメイン言語はPHPなので検索ワードは
「JavaScript foreach」
で調べたところ、JavaSccriptのforEach()
メソッドがあったので「キタコレ」という感じで実装
具体的な実装イメージは以下の通り。
const hasDummys = [
false,
true,
false
];
// 配列hasDummyの値にtrueであれば、アラートだす
hasDummys.forEach(function(hasDummy){
if (hasDummy) {
alert('不正な処理です。'); // (1
return false;
}
});
// 配列hasDummyの値に問題なければ、ログイン画面に遷移
window.location.href = '/login'; // (2
これで画面遷移前に配列内チェックができ、不正値であった場合は処理を止められる、と思っていた
結果
結論、想定外の挙動でした。
挙動としては、
(1のアラートが発令されるが、処理が止まらずに(2のログイン画面へ遷移処理が実行
という状況。
PHPのforeachであれば処理は止まるはずなのになぜ?といった具合でした。
対策
JavaScriptの他のループ処理を使う
具体的にはfor-ofを使いました。
※PHPなどのforeach的に使うなら直感的に使いやすい。
コードを以下のように書き変えました。
const hasDummys = [
false,
true,
false
];
// [ 変更 ] forEachからfor...ofに変更
// 配列hasDummyの値にtrueであれば、アラート
for(hasDummy of hasDummys){ // ★
if (hasDummy) {
alert('不正な処理です。'); // (1
return false;
}
}
// 配列hasDummyの値に問題なければ、ログイン画面に遷移
window.location.href = '/login'; // (2
実行すると、
値がfalse:問題なくログイン画面へ遷移
値がtrue:アラートがでて、ログイン画面への遷移処理は実行されない
という想定通りの挙動をしてくれました。
補足
最初に使ったforEachではfor-ofと違ってづいう挙動をするかというとforEachの場合は与えられた配列の値を一旦すべてループ処理するらしいです
上記の実例で行くと★に処理が来ると
1巡目:値がfalseなのでif文に入らない=何もしない
2巡目:値がtrueなのでif文に入り、アラート発生しreturn false
で何も返さない
=何もしない
3巡目:3巡目の処理に入り、値がfalseなのでif文に入らない=何もしない
↓
そのまま処理を続ける=処理が③に入り、画面遷移がされる
といった挙動になります。
一方、for...ofは
1巡目:falseなのでif文に入らない=何もしない
2巡目:trueなのでif文に入り、アラート発生しreturn false
で何も返さない
=何もしない
3巡目:2巡目で処理は止まるので、何も起きない
といった挙動になります。
この違いはforEach()
とfor...of
の処理の直後にconsole.logを置いて、出力されるか否かを見るとわかりやすいのでは、と思います。
おわりに
PHPとJavaScriptで同じforeachでも処理の仕方が違うのかと驚きました。
JavaScriptはループ処理が充実していてfor...in
やevery
が用意されているので、選択肢が広がったな、と実感しました。
最後までお読みいただきありがとうございました。