JavaScriptやjQueryを使ってプログラミングをしていると、配列要素をループ処理する状況が良くある。
配列をループ処理する場合、JavaScriptとjQueryとでは引数の順番など記述方法が若干異なるので、ワテは良く混乱する。
なので、今回はJavaScriptを使って配列要素をループ処理する文法をまとめてみた。
JavaScriptで配列をforEachループ処理する各種方法
⓪ インデックス式の普通のループ処理
var ary = ['0', '1', '2', ]; function func0_JS_for_i() { for (var i = 0; i < ary.length; i++) { var ary_i = ary[i]; var msg = 'ary_i=' + ary_i + ' :' + typeof (ary_i); alert(msg); } }
ワテの場合、このようにインデックス変数 i を使ってループ処理する従来式の方法が好みだ。
分かり易いし、C, C++, C# その他のどんな言語でも使える。
いや待てよ、インデックス式のforループが無い言語があるかもしれないが、もしそんな言語がありましたら教えて下さい。
上の例を実行してみる場合は↓のボタンをクリック
単にalert関数で 0 , 1 , 2 を表示するだけの関数であるが。
① forEach(function(value){…}) の例
var ary = ['0', '1', '2', ]; function func1_JS_val() { //【1】配列aryの要素valueを一個ずつ処理する。 ary.forEach(function (value) { var msg = 'value=' + value + ' :' + typeof (value); alert(msg); }); }
JavaScriptでは上の例のように、配列変数aryに対して
配列.forEach(…)
というメソッドがあるのだが、カッコの中の記述方法を良く忘れる。
最も単純なのが上の例のように引数valueを一個だけとる記述方法だ。
ループ処理関数の引数valueに配列aryの要素が一個ずつ渡って来るので、それを受け取って必要な処理を行えば良い。
でも、何番目の要素を処理しているのかを知りたい場合もある。
そういう場合は次の例がお勧めだ。
② forEach(function(value, index){…}) の例
var CRLF = '\r\n'; function func2_JS_val_ind() { //【2】配列aryの要素valueを一個ずつ処理する // (indexも取得したい場合)。 ary.forEach(function (value, index) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF; alert(msg); }); }
value 今処理している配列要素の値
index 今処理している配列要素のインデックス番号
の二つの情報が得られるので、ワテはこの方式を良く利用する。
以下、あまり使わないと思うが、今回JavaScriptの配列のループ処理を調査していて見付けた記述方法。
参考にして下さい。
③ forEach(function(value, index, 第三引数){…}) の例
function func3_JS_val_ind_tra() { //【3】第三引数にtraversedObjectというのがある。 // aryそのものが来るようだが何に使うのかな? ary.forEach(function (value, index, traversedObject) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF + 'trObj=' + traversedObject + ' :' + typeof (traversedObject); alert(msg); }); }
上の例のように、ループ処理関数に第三引数があり、
traversedObject
と言う名前で呼ばれているようだ。
実際に実行してみると、毎回のループ処理でこの引数には、今処理している配列そのものが渡って来るようだ。
なので、上のような記述をしなくても、ループ内で
ary
そのものを参照してもよいかも。
いずれにしても、どういう状況でこの第三引数のtraversedObjectを使うのか良い例が思いつかない。
追記(2016/11/25)
forEach(function(value, index, 第三引数){…}) を使う場面が分かった。
配列の各要素をループ処理中に、その要素の値を変更したい場合だ。
その例えばこういう風にしても値は変わらない。
var arr = [ 0, 1, 2 ]; arr.forEach(function(val){ val = val*10; })
ループを脱出しても arr は元のままだ。
arr.forEach(function(val, index, arrOrg) { arrOrg[index] = val*10; });
とすると、ループ脱出後には arr の各要素は値が10倍されている。
つまり第三引数には今処理中の arrそのものが渡って来るのでそれを indexを使って値を変更するのだ。
なお、よく考えてみるとこれと同じ処理は、
arr.forEach(function(val, index) { arr[index] = val*10; });
としても可能である。
これでも値が10倍出来る。
と言う事で、第三引数を敢えて使っても良いが、使わなくても良いと言う結論になりそう。
thisの意味
さて、JQueryを使っているとthisが良く出て来る。
$(this)などのように使う場合もある。
thisの意味は使う場面で微妙に意味が変わるのでワテは今でも良く混乱するのだが、今回調査しているJavaScriptのforEachループメソッド内でもthisが使えるのかなと思ってやってみた。
つまりforEachループ内でthisを使うと、
- 今処理している配列そのもの
- 今処理している一個の要素
どちらかの値が得られるのかなと思ったが、そうではないようだ。
④ forEach(function(){…}) 内でthisはundefinedとなる
function func4_JS_this_undef() { //【4】ループ内でthisを参照してもundefinedになるので、 // こういう方式は不可 ary.forEach(function () { msg = this.value; alert(msg); }); }
実際に実行してみると、thisはundefinedになる。
thisはundefinedになってしまうが、thisのような感じの変数を使いたい場合には、
thisObj
という普段あまり目にしない引数が使えるようだ。
その例を次に示す。
⑤ forEach(function(val, ind){…}, thisObj) の使い方
function func5_JS_thisObj() { //【5】そういう場合は、thisObjを自分で定義しておいて // ループ内で参照出来る。 var thisObj = { myalert: function (value, index) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF; alert('[myalert]で表示' + CRLF + msg); } }; ary.forEach(function (value, index) { thisObj.myalert(value, index); }, thisObj); }
事前にthisObjというオブジェクトを作成しておいて(変数名はもちろんthisObj以外でも良い)、それをループ内で参照するという方法だ。
今の例ではmyalert()というメソッドを持っているので、それを
thisObj.myalert()
のように呼び出せる。
う~ん、こういう記述方法はどういう時に使うと便利なのか、今一つ良い例が思いつかない。
なお、言うまでもないが value, indexは不要なら省略しても良い。
上記の例の完全なHTML
今までの例を自分のパソコンで試してみたい人は、以下のHTMLをコピペして
test.html
などという適当なファイル名で保管すると良い。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <input type="button" value="JavaScript配列実験0" onclick="func0_JS_for_i();" /> <input type="button" value="JavaScript配列実験1" onclick="func1_JS_val();" /> <input type="button" value="JavaScript配列実験2" onclick="func2_JS_val_ind();" /> <input type="button" value="JavaScript配列実験3" onclick="func3_JS_val_ind_tra();" /> <input type="button" value="JavaScript配列実験4" onclick="func4_JS_this_undef();" /> <input type="button" value="JavaScript配列実験5" onclick="func5_JS_thisObj();" /> <script> var CRLF = '\r\n'; var ary = ['0', '1', '2', ]; function func0_JS_for_i() { for (var i = 0; i < ary.length; i++) { var ary_i = ary[i]; var msg = 'ary_i=' + ary_i + ' :' + typeof (ary_i); alert(msg); } } function func1_JS_val() { //【1】配列aryの要素valueを一個ずつ処理する。 ary.forEach(function (value) { var msg = 'value=' + value + ' :' + typeof (value); alert(msg); }); } function func2_JS_val_ind() { //【2】配列aryの要素valueを一個ずつ処理する // (indexも取得したい場合)。 ary.forEach(function (value, index) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF; alert(msg); }); } function func3_JS_val_ind_tra() { //【3】第三引数にtraversedObjectというのがある。 // aryそのものが来るようだが何に使うのかな? ary.forEach(function (value, index, traversedObject) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF + 'trObj=' + traversedObject + ' :' + typeof (traversedObject); alert(msg); }); } function func4_JS_this_undef() { //【4】ループ内でthisを参照してもundefinedになるので、 // こういう方式は不可 ary.forEach(function () { msg = this.value; alert(msg); }); } function func5_JS_thisObj() { //【5】そういう場合は、thisObjを自分で定義しておいて // ループ内で参照出来る。 var thisObj = { myalert: function (value, index) { var msg = 'value=' + value + ' :' + typeof (value) + CRLF + 'index=' + index + ' :' + typeof (index) + CRLF; alert('[myalert]で表示' + CRLF + msg); } }; ary.forEach(function (value, index) { thisObj.myalert(value, index); }, thisObj); } </script> </body> </html>
文字コードはUTF-8で保存する。SJISなどで保存すると文字化けするので。
保存したら、そのtest.htmlファイルをダブルクリックするか、あるいはInternet Explorerの画面にドラッグすると実行出来る。
まとめ
JavaScriptのforEach(…)の使い方を調べてみた。
forEach(function(value){...}) forEach(function(value, index){...}) forEach(function(value, index, traversedObject){...}) forEach(function(value, index){...}, thisObj)
など各種の方式が有る事が分かった。
こうやってブログ記事に書いておけば、忘れてもあとで見直せばすぐに思い出せる。
本を読む
本をじっくり読むよりもネットを利用して断片的なコードを入手してコピペして使っている人も多いと思う。
上記の本のタイトルは、そういうワテみたいな人間に最適な感じの本だな。
何となくJavaScript
コピペ式でプログラムを書いていると断片的な知識しか得られないので記憶に残りにくい。
やっぱり一冊じっくりと本を読むのがお勧めだな。
ちなみに、著者は
田中康夫 氏ではないようだ。
そういうワテみないた人は、次世代のEcmaScript 6の本を先読みしておくのも良いかも。
時代を先取りだ。
コメント