JavaScriptのループについて(配列編)
はい、前回の続きです。
配列の場合
配列のループ方法で調べるとこういう議論もあったりしますが。
JavaScriptで配列をループで処理するベストな書き方は?
まず、for...inは避けましょうっていう傾向はあるみたい。
Effective JavaScriptでも配列の反復処理にはfor...inじゃなくてforを使おうっていう項目があったり。
- 作者: David Herman,吉川邦夫
- 出版社/メーカー: 翔泳社
- 発売日: 2013/02/19
- メディア: 大型本
- 購入: 1人 クリック: 109回
- この商品を含むブログを見る
Effective JavaScriptではfor...inを使用したときにキーと値を混同してしまう可能性について述べていて、for使った方がいいよーって主張してます。
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var total = 0; for(var num in numbers) { total += num; // 正しくはtotal += numbers[num]; } console.log(total); // 期待している結果にはなりません
もちろん、プロトタイプ汚染の可能性もあるので、hasOwnPropertyのチェックも入れておかないとですね。
と、まぁ色々面倒なのでfor...inはやめよう。。。
あとは古典的なforループか、ES5のArray.prototype.forEachか。
forはforEachに比べて記述が冗長で、初期化式のvar付け忘れや終了条件の記述ミスなどの恐れがあります。
// iにvarを付け忘れているためグローバル変数になってしまう for(i = 0; i<length; i++) {...} // 一回余計な繰り返し for(var i=0; i<=arrayLength; i++) {...}
けれども、forはbreakを使うことでループの中断が可能。
forEachだとtry-catchで中断するしかない?ので多少見辛くなる感じが。。。
// for使用 function totalUntilZero(array) { var result = 0; for(var i=0, len=array.length; i<len; i++) { if(array[i] === 0) { break; } result += array[i]; } return result; } console.log(totalUntilZero([5,8,2,3,0,10,2,9])); // forEach使用 function totalUntilZeroForEach(array) { var result = 0; // try-catchでthrowして中断 try { array.forEach(function(num) { if(num === 0) { throw result; } result += num; }); } catch(e) { // 特に何もしない } return result; } console.log(totalUntilZeroForEach([5,8,2,3,0,10,2,9]));
もっとも、forEachが使用できるブラウザなら、filterやmap、some、everyなどの反復メソッドも使用できるので、ケースバイケースでそれらを使い分ければ割とスッキリ書けるんですけどね。
function totalUntilZero(array) { var result = 0; // Array.prototype.everyはコールバックがfalseを返すまで処理を繰り返す array.every(function(num) { if(num === 0) { return false; // break } result += num; return true; // continue }); return result; } console.log(totalUntilZero([5,8,2,3,0,10,2,9]));
あれ...書いてみると意外とreturnが多くて、そんなにわかりやすいとは言えない?
まぁいいか。
あと、forEachってインデックス使用できないって思ってたんですけど、コールバックに引数として渡せるっぽいです。
forEach - MSDN
インデックス使うような処理はforで、って思ってたんですけどforEachでもできますね。
結論
シンプルな記述で済むので、forEachとか反復メソッドを使えるところは積極的に使っていければいいのかなと思いました。
ただ、複雑な処理が必要で、ギリギリまでループ内の処理を最適化したいときはforが良いときもあるかもしれないです。
試してないからわからないけども。
改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/30
- メディア: 大型本
- この商品を含むブログを見る
徹底マスター JavaScriptの教科書 プログラミングの教養から、言語仕様、開発技法までが正しく身につく
- 作者: 磯博
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2017/03/18
- メディア: Kindle版
- この商品を含むブログを見る