Javascriptのfor系統まとめ(for,for..in,for..of,forEach)
TL;DR.
ソースコード。
実行はNode.jsで。
はじめに
for...inとfor...ofどっちがどっちか忘れるからまとめる。
ついでに他のforについてもまとめて、個人的なメリットデメリットも記載する。
forの種類
- for
- for...in
- for...of
- Array.forEach()
for
単純なfor。指定した回数繰り返し処理をしてくれる。
// 単純ループ let sum = 0; for (let i = 1; i <= 10; i++) { sum += i; } // リスト全ループ const list = [1, 3, 5, 7]; for (let i = 0; i < list.length; i++) { console.log('value:', list[i]); }
メリット
わかりにくいとかは無いと思う。
これといったメリットは思いつかなかった。
デメリット
いちいち書くのがめんどくさいと思う。
for...in
オブジェクトのプロパティ(キー)分ループしてくれる。
const obj = {'a':1, 'b':2, 'c':3}; for (const value in obj) { console.log('key:', value); console.log('value:', obj[value]); }
メリット
オブジェクト(連想配列)のループができる。
デメリット
配列に使うとあんまりよくない。
const list = [1, 3, 5]; list.text = 'hoge'; list.func = function(){ console.log('hoge'); } for (const key in list) { console.log('key:', key); console.log('value:', list[key]); }
出力は下記の通り。
配列のループは直感だと値が逐次取れるイメージだと思う。
実際はindexが取れる。
しかも後から追加した変なのも普通に取れてしまう。
key: 0 value: 1 key: 1 value: 3 key: 2 value: 5 key: text value: hoge key: func value: function (){ console.log('hoge'); }
当たり前だけど、TypeScriptでも変わらない。
class test { constructor() { const list:number[] = [1, 3, 5]; list['text'] = '1'; for (const value in list) { console.log(value); } } } new test(); /* 結果 0 1 2 text */
for...of
プロパティの値分ループするfor文。
Javaの拡張forが近しい動きだと思う。
const list = [1, 3, 5]; for (const value of list) { console.log(value); }
メリット
下みたいなことしても問題なく出力してくれる。
const list = [1, 3, 5]; list.text = '1'; for (const value of list) { console.log(value); }
デメリット
ES6で導入されたから、古いブラウザだと動かない。
ブラウザ変えろ。
Array.forEach
配列要素に対しての繰り返しを行ってくれるメソッド。
できることはfor...ofとほぼ同じ。
const list = [1, 3, 5]; list.forEach(element => { console.log(element); });
callbackの引数全指定した場合は下記の通り。
下記例のarrayについては、特に何もしなければループ中同じ値が取れる。
const list = [1, 3, 5]; list.forEach((element, index, array) => { // 取り出した配列の値 // 例:1,3,5 console.log('element:', element); // 配列のインデックス // 例:0,1,2... console.log('index:', index); // ループしてる配列自身 // 例:[1, 3, 5] console.log('array:', array); });
メリット
indexを使うことができる。
(人によると思うけど)見やすい。
callbackだから関数を切り出せる。
(切り出されているところを見たこと無いし、for...ofでも同じ気がするけど)
const loop = element => { console.log('callback:', element); } list.forEach(loop);
デメリット
あくまでcallbackなので、breakできない。
※continueはreturnと書けばOK。
速度に不安があるみたいなので、速度が重要な 場合は使わないほうが無難だと思う。
おまけ
オブジェクトに対してforEachかけるなら、Object.keys()
と組み合わせる。
const obj = { 'a': 1, 'b': 2, 'c': 3 }; Object.keys(obj).forEach(key => { console.log('key:', key); console.log('value:', obj[key]); });
まとめ
for...in以外ならどれでも良いと思う。
軽く調べた感じ、for...ofが優勢だった。
配列にしか使えないforEachと違って、
for...ofはiterable object
ならなんでも使えるらしい。
更に速度面に不安なのもあると思われる。
個人的には速度をとても気にする必要もないし見やすいので、
breakする必要が無いならforEachを使ってる。