いつ俺〜いつから俺ができないと錯覚していた?〜

社会人ブロガー。大手メーカーでソフトウェア開発をしている人。プログラミングは結構得意。

JavaScriptの色々なfor文|for・for-each・for-in・for-of

f:id:shun_prog0929:20160524122314p:plain

 

for文は、繰り返しを扱うための構文です。しかし、一口に繰り返しを扱うと言っても、JavaScriptのfor文には色々な書き方があります。それぞれのfor文は、独自の使い方・意義がありますので、覚えて使いこなしたいですね。

 

というわけで、今回はfor文の色々な書き方を紹介します。

 

 

for(指定回数の繰り返し)

まずは、基本の書き方です。指定回数の繰り返しをします。

 

forの書き方

for は以下のような構文です。

 

for([初期化処理]; [終了条件]; [各反復の最後の式]) {
  文
}

 

初期化処理は、繰り返しの前に行う処理です。ここには、式と変数宣言を書くことができます。一般的には、変数宣言か代入式でカウンタ変数の初期化を行います。

 

終了条件は、繰り返しを終えるための条件式です。この条件式がtrueになった時に繰り返しを終了します。

 

各反復の最後の式は、実際に繰り返し行う処理の最後に、毎回実行される式です。一般的には、カウンタ変数をインクリメントする式を記述します。

 

forの例

例えば、0から9までの総和を求めるプログラムは以下のように、繰り返し構文で実現できます。

 

var sum = 0;
for(var i = 0; i < 10; i++) { // iが0から9までの間の繰り返し(毎囘最後に i++ を実行)
  sum += i;
}

 

また、この繰り返し構文は配列を利用する場面も多いです。

 

var sum = 0;
var array = [1, 3, 4, 7];
for(var i = 0; i < array.length; i++) { // 配列の長さ分の繰り返し
  sum += array[i];
}

 

このように、array.length(配列の長さ)を用いて終了条件を指定します。また、配列の要素分の繰り返しは、後述のArray.forEachを使うことも考えられますので、そちらも参考にしてください。

 

for in(オブジェクトのプロパティ名についての繰り返し)

for-in文は、オブジェクトに存在するプロパティについて、プロパティの名前を順不同で取り出していき、処理を実行する構文です。

 

for-inの書き方

for-in文は以下のような構文です。

 

for([プロパティ名を格納する変数] in [オブジェクト]) {
  文
}

 

指定したオブジェクトについて、プロパティ名を順不同で取り出し、inの前に定義した変数に格納してから処理を実行します。この時、繰り返しはすべてのプロパティについて処理を行うと終了します。

 

for-inの例

オブジェクトのプロパティの中の数値を全て足すプログラムの例です。

 

var sum = 0;
var obj = { a:1, b:2, c:3 };
for(var name in obj) { // オブジェクトの中のプロパティ名を取り出す。
  sum += obj[name];
}

 

このような順不同でも問題ないような場面で使うといいでしょう(ただし、この場合は後述のfor-ofの方が自然に書けます)。 

 

for-inの注意点

for-in文はオブジェクトに含まれる列挙可能なプロパティを全て取り出します。なので、予期せぬプロパティの参照などが起こる場合があります。

 

例えば、以下のように配列オブジェクトにtypeというプロパティを追加すると、配列の要素だけでなく、追加されたプロパティまで取り出してしまいます。

 

var array = [1, 5, 9];
array.type = "number";
for(var name in array) {
  console.log(name); // => 0, 1, 2, type
}

 

このようなプロパティの追加には注意するべきでしょう。

 

また、prototypeをさかのぼって見てしまうことにも注意です。

 

var Human = function(name) {
this.name = name;
}
Human.prototype.type = "Human";
var taro = new Human("taro"); for(var name in taro) { console.log(taro[name]); // => taro, Human }

 

これについては、Object.keysを使うとprototypeのプロパティを取らずに済むので、これを使うといいです(継承関係が複雑なときなどに使うといいでしょう)。

 

var Human = function(name) {
this.name = name;
}
Human.prototype.type = "Human";
var taro = new Human("taro");
var taroKeys =Object.keys(taro); for(var i in taroKeys) { console.log(taro[taroKeys[i]]); // => taro }

 

for of(オブジェクトのプロパティの値についての繰り返し)

先ほどのfor-in文がプロパティ名を取得したのに対して、for-of文ではプロパティの値を取得します。また、for-of文は繰り返し処理を行うことを前提としたオブジェクト(配列やリストなど*1)しか扱うことはできません。

 

for-ofの書き方

for-of文は以下のような構文です。

 

for([プロパティの値を格納する変数] of [反復可能なオブジェクト]) {
  文
}

 

書き方自体はfor-in文とほぼ同じですが、ofの後にかけるのは、反復処理が可能なオブジェクトのみです。

 

for-ofの例

先に示した、配列を用いた繰り返しの例を、for-ofで書くと以下のようになります。

 

var sum = 0;
var array = [1, 3, 4, 7];
for(var value of array) { // オブジェクトの中のプロパティ名を取り出す。
  sum += value;
}

 

for-ofの注意点

for-of文は、ECMAScript6から導入された構文です。ですので、ブラウザのバージョンが古い場合に動かない可能性があります。もし動かない場合は、後述のArray.forEachで配列に対する繰り返しを行うことができるので、そちらを利用してください。

 

Array.forEach(配列の各要素についての繰り返し)

こちらのforEachは、配列の各要素について繰り返し処理を行うためのメソッドです。できることは前述のfor-of文と同じで、こちらは配列のみに適用可能です。

 

JavaScriptでfor-eachと言ったときには、このArray.forEachを指すことが多いです。for-each-in構文というものがありましたが、現在は廃止されています。

 

Array.forEachの書き方

Array.forEachの書き方は以下のようになります。

 

array.forEach([コールバック関数], [オブジェクト(省略可)])

 

arrayは、繰り返し処理を行いたい配列です。コールバック関数では、繰り返しで行いたい処理を記述した関数を渡します。

 

第2引数のオブジェクトは、コールバック関数におけるthis(自分自身を指すオブジェクト*2)になります。

 

Array.forEachの例

先ほどまでの配列を用いた繰り返しの例をArray.forEachで書くと以下のようになります。

 

var sum = 0;
var array = [1, 3, 4, 7];
array.forEach(function(value) {
sum += value;
});

 

まとめ

今回は、JavaScriptのfor文について解説しました。繰り返しを扱う基本的な構文ですので、しっかりと理解しておきましょう。

 

 

*1:iterableなオブジェクト

*2:自分自身のインスタンス