どうも、カメ助(@kamesuke_blog)です。
JavaScriptで、繰り返し処理を行う場合にはよく「for-in」、「for-of」、「forEach」を使用すると思います。ただし、処理内容が似ているため、何となく使用していると意図しない不具合が起こる可能性があります。
そのため、「for-in」、「for-of」、「forEach」文の特徴と注意点についてまとめましたので共有します。
javascriptの繰り返し処理を行う際にの参考になれば幸いです。
はじめに
for文(繰り返し処理)の仲間には、Javaの拡張for文に近いものがあります。まとめるとは次の通りです。
- for…in:オブジェクトの列挙可能なプロパティに対して順不同で繰り返し処理を行う
- for…of:iterableオブジェクトの個々のプロパティに対して繰り返し処理を行う
- forEach:配列に用意されているメソッドで、配列の各要素に対して一度ずつ処理を行う
それぞれについて解説していきます。
「for…in」文
「for…in」文の基本書式
「for…in」文の基本書式は次の通りです。
1 2 3 4 |
//JavaScriptの「for-in」文 for ([変数] in [オブジェクト]) { [実行する処理] } |
「for…in」文は、オブジェクトの列挙可能なプロパティに対して順不同で繰り返し処理をします。「for…in」文の一般的な動作として、「オブジェクトのプロパティを1つずつ変数に代入→処理実行」を繰り返します。そして、取得できるプロパティが無くなれば自動的に処理を終了します。
「for…in」文の注意点
「for…in」文の注意点として、以下の2つがあります。
①:データ量が多いとすごく遅い(多すぎるとエラーが出る危険性もある)
②:順不同に処理が実行されるので、ループする順番は保障されない
②について簡単に説明します。例として「1, 2, 3」の順序で処理を行うことを想定します。しかし、「for…in」文では、「3, 2, 1」といった処理の順序になる場合もあれば、「2, 3, 1」になる場合もあります。
上記①、②の注意点が繰り返し処理をする場合に、不具合の温床になることがあるので、基本的に「for…in」を使用しないようにしましょう。
特別な事情がない限り、「for…in」文を使用しない方がいいです。
「for…in」文でオブジェクトのプロパティを取得
「for…in」文の基本的な使用例である、オブジェクトの全プロパティを出力します。
1 2 3 4 5 6 7 8 9 |
let userData = { name: 'カメ助', age: 5, address: '大阪府大阪市××区〇〇〇' } for( let item in userData) { console.log( item ); } |
実行結果
1 2 3 |
name age address |
この例では、「userData」というオブジェクトを作り、そのプロパティを全て出力しています。「for-in」文の繰り返し処理を行うことで、とても簡単にオブジェクトの全プロパティを列挙できています。
プロパティ値を出力する場合は、console.logの「item」→「userData [ item ]」に変更してください。
「for…of」文
「for…of」文の基本書式
「for…of」文を書くときの書式は次の通りです。
1 2 3 4 |
//JavaScriptの「for…of」文 for ( [変数] of [iterableオブジェクト] ) { [実行する処理] } |
「for…of」文は、「iterableオブジェクト」の各値を1つずつ順番に変数へ代入して処理を実行します。
ここで『「iterableオブジェクト」って何ですか?』と思われる方も多いと思いますので、簡単に説明しておきます。
反復処理可能なプロパティをもつオブジェクト
(例)配列、文字列、Map、DOMコレクション
「for…of」文の注意点
「for…in」文の注意点として、以下の2つがあります。
①:Iterable(イテラブル)オブジェクトしか使用できない
②:ECMASCript2015から導入された新しい構文のため、IEなどの古いブラウザは対応していません
配列やMapなど、繰り返し処理を行いたいオブジェクトはiterableオブジェクトなので、①についてはあまり気にしないでいいです。②については、IEなどの古いブラウザを対象にする場合は、「for…of」文は使用できないので注意しましょう。
古いブラウザが対象でなければ、積極的に「for…of」文を使用しよう!
「for…of」文で配列の全要素を取得
「for…of」文の基本的な使用例である、配列の全要素を出力します。
1 2 3 4 5 6 |
//配列の要素を全て表示 let array = [0, 1, 2]; for( let item of array ) { console.log( item ); } |
実行結果
1 2 3 |
0 1 2 |
「for」文でも同じことができますが、「for…of」文は「ループ回数」や「カウンタ変数」などを意識せずに扱えるのでシンプルで使いやすい構文になるよ。
おまけ:「for…of」文と「for…in」文の違いについて
「for…of」文は、先ほどの「for…in」と構文が非常に似ていますよね。それぞれの違いについて押さえておきましょう。
「for…of」文と「for…in」文は、配列を対象にした場合に挙動が異なります。
例として配列[1,3,5]に対してそれぞれ処理することを考えます。
「for…in」文の場合は、以下の通りです。
1 2 3 4 5 6 7 |
//配列を「for…in」文で処理する for(let i in [1, 3, 5] ) console.log(i); //出力結果 0 1 2 |
「for…of」文の場合は、以下の通りです。
1 2 3 4 5 6 7 |
//配列を「for…of」文で処理する for(let i of [1, 3, 5] ) console.log(i); //出力結果 1 3 5 |
出力結果が異なっているのが分かりますね。配列の場合、「for…in」文は【index】が出力され、「for…of」文は【value】が出力されています。
配列を繰り返し処理する際にイメージするのは「for…of」文の方であると思いますので、配列の場合は「for…of」文を使用しましょう。
「forEach」文
「forEach」文の基本書式
「forEach」文の書式は次の通りです。
1 2 3 |
[配列名]= [要素1,要素2,…]; [配列名].forEach([コールバック関数] ) ; |
配列の要素1つずつに対して、コールバック関数に記述した処理を実行します。
「forEach」文で配列の要素を取得
例として、配列を1つ作成し、その「配列の要素」を全て表示させましょう!
1 2 3 4 5 |
let lists = [0, 1, 2]; lists.forEach( function( value ) { console.log( value ); }); |
実行結果
1 2 3 |
0 1 2 |
この例では、コールバック関数内で配列の要素をコンソールに出力しています。
「forEach」文で使える3つの引数
「forEach」文のコールバック関数には、3つの引数を受け取ることが可能です。
1 2 3 |
array.forEach( function( value, index, array ) { [実行する処理] }); |
それぞれの引数の意味は、次のとおりです。
- 「value」:配列の要素
- 「index」:配列の要素番号
- 「array」:現在処理している配列
引数の使用方法について見ていきましょう。次の例は、コールバック関数の引数に「value」、「index」を使用するサンプルです。
1 2 3 4 5 |
let lists = ['カメ', 'メダカ', 'カラス']; lists.forEach( function( value, index ) { console.log( 'index: ' + index + ' | value: ' + value ); }); |
実行結果
1 2 3 |
index: 0 | value: カメ index: 1 | value: メダカ index: 2 | value: カラス |
この例では、コールバック関数の引数「value」、「index」を使って、要素の「要素番号」と「要素」をコンソール出力しています。
「forEach」文は途中でbreakできない
「forEach」文を使う上で注意するべき点として、途中でループ処理を抜けられないという点が挙げられます。(例外処理は除く)
例えば次のようなコード例を想定してみましょう!
1 2 3 4 5 6 |
var item = [6,2,4,7,10]; item.forEach(function(value) { if(value === 7) break;//ここでエラー console.log( value ); }) |
この例では、配列の要素が「7」の場合にbreakして処理を中断させるように書いていますが、これはエラーになります。
「forEach」文ではコールバック関数内でのbreakやcontinueの記述が認められていないので、繰り返し処理の途中で中断や処理をスキップしたい場合には、単純に「for」文を使いましょう。
「for」文で記載した場合は次の通りです。
1 2 3 4 5 6 |
var item = [6,2,4,7,10]; for(var i=0; i<item.length; i++) { if(item[i] === 7) break;//「for」文の途中で処理を中断 console.log(item[i]); } |
実行結果
1 2 3 |
6 2 4 |
この例では、「for」文を使って要素が「7」の場合にbreakして処理を中断しています。
途中でループ処理を抜けることが想定されるのであれば「for」文を使いましょう。
まとめ
各繰り返し処理の特徴は以下の通りです。
これらの特徴をベースに意識して、ぜひ自分なりの活用方法を見つけてfor文をマスターしよう!
コメント
コメント一覧 (6件)
[…] ※今回の問題は、forEach文を使用しています。forEach文の解説はこちら […]
[…] 拡張for文の解説ページはこちら […]
[…] 拡張for文の解説ページはこちら […]
[…] 拡張for文(for…in/for…of)の解説ページはこちら […]
[…] 拡張for文(for…in/for…of)の解説ページはこちら […]
[…] 【JavaScript入門】これだけは覚えておけ!foreach / for-in / for-of […]