あらすじ
JavaScriptのforEach
関数にはいくつか使いにくい部分があると思います!
- HTMLCollectionのような「配列のようだけど配列じゃない」データにたいして使えない。
- keyとvalueどちらも参照したい場合、第一引数がvalue、第二引数がkeyとなるように指定しなければいけなくて、微妙に直感的じゃない。
- PHPのforeachと比べると、書き順が違うので、どちらも使う職場では混乱する。
※ PHPのforeach: foreach( $配列 as $キー => $値 ){ ...
※ JavaScriptのforEach: 配列.forEach( (値, キー) => { ...
上記のような問題点を解決するため、オリジナルのforeach関数を作ってみました!
参考記事: JavaScriptのループはどれが一番高速なのか
参考記事: 文字列を数値に変換する方法と処理速度
コード
for...in
を使います!
function foreach( roopTarget, process ){
for( const i in roopTarget ){
if (!roopTarget.hasOwnProperty(i)) { continue; } // この行の必要性については、コメント欄をご覧ください。
switch( process.length ){ // process が関数だった場合、 length で引数の数が判別できる。
case 0: process(); break;
case 1: process( roopTarget[i] ); break;
case 2: process( Number(i), roopTarget[i] ); break; // i が文字列型になっているので、数値型に変換しておく。 // 文字列→数値変換は Number() が早いらしい。
default: console.error('引数が多すぎます!'); return;
}
}
}
ちなみに、ループしたいオブジェクトが NodeList や HTMLCollection だった場合、
数値のキーと文字列のキーが混在しています。
中身の要素だけ処理したい場合は、switch文の前に「キーが文字列だった場合は処理しない」というコードを挟むといいと思います!
if( isNaN(i) ) continue;
おわり
当初の問題を解決したforeach関数ができあがりました!
これを使えば foreach( 配列, (キー,値)=>{ ...
という書き方で、
どんなデータでもforeachが使えるようになります!
「ここまでする必要あるのか?」
多分、まったく必要ないです!!
普通に for...in
や for...of
でぶん回すのが個人的には好きです! ご拝読ありがとうございました!!
謝罪
すみません、投稿時点では length
プロパティを使ってfor文でループするパターンの書き方も掲載していたのですが、
キーが文字列になっているオブジェクトに対して利用できないことに気づいて、削除しました。