BLOG

JavaScript初心者から中級者になるために知っておきたい7つのループメソッド

2020/06/04


こんにちは!2019年の10月にBRISKへ入社しました、以下のブログを書いているものです。
(よかったらのぞいてみてください!)

25歳・未経験からWebエンジニアになってみた【中途採用ブログ2019年10月~12月】
25歳・未経験からWebエンジニアになってみた【中途採用ブログ2020年1月~3月】

少し前にVue.jsを扱う案件に携わりました。
そこで、mapやsome,findなどのJavaScriptのループメソッドをはじめて扱いました。
ネットで調べてもしっくりくる記事がすくなかったので今回はそれらのメソッドについてまとめようと思います。

この記事で登場する用語・記法

各メソッドの具体的な説明に入る前に、登場する用語や記法について軽く触れておきます。

var , let , const

var,let,constは変数を宣言する際に使うキーワードです。
let,constはES2015(ES6)から導入されました。
ES6とは、2015年に標準として策定されたJavaScriptの新しい文法です。

これらの主な違いは以下のようになります。

var let const
初期値の省略 OK OK NG
再宣言 OK NG NG
再代入 OK OK NG

以下、上記表について具体的に見ていきます。

初期値の省略

constは初期値の省略ができません。

このように、constは定数(定まった値)として扱われるため、初期値がないとエラーになります。

再宣言

varは再宣言できますが、let,constはできません。

再代入

var,letは再代入できますが、constはできません。

以上が、var,let,constの説明です。

なお、こうした新しい記述は全ブラウザが対応しているのかが気になるところです。

varは基本的にどのブラウザでもOKですが、const,letはレガシーなブラウザ(例えばIE10)では使うことができません。

ただし、Babelなどのトランスパイラを使用すればconst,letを使ってもvarに置き換えてくれます。
よって、「トランスパイラが使えない」+「レガシーブラウザも対応しなければいけない」という状況であればvarを使い、そうでなければconst,letを使うのがよいでしょう

コールバック関数

コールバック関数は、他の関数に引数として渡す関数です。
「関数Aの処理が終わった後に、関数B(コールバック関数)を実行したい」などの目的で使用します。
言葉だとわかりずらいので例を見てみましょう。

上記の.on()メソッドの第二引数として渡されている関数がコールバック関数です。
この場合、「クリック」という処理が終わった後に、コールバック関数の処理内容が実行されます。

アロー関数

この記事ではアロー関数を使用していますので説明しておきます。

アロー関数は、ES2015(ES6)から利用可能になった新しいJavaScriptの構文の一つです。

アロー関数は以下の2つの理由から導入されました。

1.関数を短く書きたい
2.thisを束縛したくない

※特に2.が結構重要です。(アロー関数やthisの挙動に関しては今後記事にしたいと思います。)

アロー関数で書くと例えば上記のコードは以下のようになります。

アロー関数はとにかく省略がすごいです(語彙力…)
例を見てみましょう。

上記のコードは、arg1という引数を受け取り、その引数を単純にreturnするhoge関数です。

これをアロー関数で書くと以下のようになります。

さらに、関数に渡される引数が1つの場合、()を省略できます。
※引数がない場合は省略できません!!!

さらにさらに!
処理内容が1行の場合は、{}を省略できます。
また、文の返り値がそのまま返り値とみなされるのでreturnという文言すら要らなくなります。(すごい)

ここで、先ほどのコールバック関数で紹介したコードをアロー関数で書き換えると以下のようになります。

なお、アロー関数はInterner Explorer(IE)では対応していないので
IEまで対応させてコードを書きたい場合は、Babelなどのトランスパイラを使わないといけません。

テンプレートリテラル

テンプレートリテラルはES2015(ES6)から利用可能になった新しいJavaScriptの構文の一つです。

色々な機能があるのですが、ここではこの記事で扱っている記述についてのみ限定して解説します。

テンプレートリテラルでは以下のように記述することができます

ポイントはバッククォート${ }です。
これを使うことで、今までプラス記号で文字を結合していたものがだいぶすっきり書けるようになりました。
従来の書き方↓

配列

配列は各括弧[ ] の中に値が格納されている形のものを指します。
複数の要素を配列に格納したい場合は、カンマで区切ってあげます。

オブジェクト

オブジェクトは波括弧{ } の中にキー(プロパティ)と値がセットになって格納されている形のものを指します。
複数の要素をオブジェクトに格納したい場合は、カンマで区切ってあげます。

注意事項

基本的な用語がわかったところですが、この記事を読むにあたり、いくつか意識してほしいことがあります。

意識してほしいこと1

この記事で紹介するループメソッドはオブジェクト型には使用できません。
(なんでだよー!!とか言わないでください。そういう仕様なのです。。。)

つまり、○○.map()とかの○○は配列でなければならないということです。
○○がオブジェクト型だと機能しません。

もし、オブジェクトに対してこれらの関数を使用したい場合はオブジェクトを配列に変換してあげないといけません。
やり方は以下の記事などを参考にするとよいでしょう。
ちょっとつまったjsでのobject⇒array変換

意識してほしいこと2

このあとループメソッドの紹介をしていくわけですが、ぜひ自分で同じコードを書きながら理解してほしいです。

でもいちいちエディタを立ち上げるのは面倒ですよね。
そんな方は以下のサイトを使いましょう!
エディタを立ち上げずとも簡単に実行結果を見ることができるのでオススメですよ♪
JS Bin
他にも類似のサービスはあるので色々と調べてみるのもよいですね

さて、それでは次からこの記事で扱うループメソッドを紹介していきます!!

forEach()

全ての要素に対してコールバック関数を一度ずつ実行します。
map や filter とは異なり新しい配列は生成しません。

使用例

行われていること

ループ回数 elmの中身 sumの値
1 10 0(sumの初期値)+10 = 10
2 20 10(ループ1終了後のsumの値)+20 = 30
3 30 30+30=60
4 40 60+40=100

elmにelmsの値ひとつひとつが渡ってきて、それに対してコールバック関数を実行しています。
elmという名前は別にelmじゃなくても、xやyなど好きな名前にしてOKです。

map()

全ての要素に対してコールバック関数を一度ずつ実行します。
返り値からなる新しい配列を生成します。

使用例1

行われていること1

ループ回数 elmの中身 処理内容(elm*10) 返り値(return)
1 10 10*10=100 [100]
2 20 20*10=200 [100,200]
3 30 30*10=300 [100,200,300]
4 40 40*10=400 [100,200,300,400]

使用例2

行われていること2

ループ回数 objの中身 処理内容(obj.key または obj[‘key’]) 返り値(return)
1 {key: 1, value: 10} 1 [1]
2 {key: 2, value: 20} 2 [1,2]
3 {key: 3, value: 30} 3 [1,2,3]

filter()

全ての要素に対してコールバック関数を一度ずつ実行します。
返り値で 、true を返した要素からなる新しい配列を生成します。

使用例

行われていること

ループ回数 elmの中身 処理内容(elm % 20 === 0 かチェックする) 返り値(hoge)
1 10 20で割るとあまりが0ではないのでfalse [] (まだ空の配列)
2 20 20で割るとあまりは0なのでtrue [20] (trueになった要素が入る)
3 30 20で割るとあまりが0ではないのでfalse [20]
4 40 20で割るとあまりは0なのでtrue [20, 40]

some()

true を返す要素が見つかるまで、要素に対して一度ずつコールバック関数を実行します。
true を返す要素が見つかるとtrue を返し、ループが終わります。

使用例

行われていること

ループ回数 elmの中身 処理内容
(elm >= 20 かチェックする)
返り値(hoge)
1 10 20以上ではないのでfalse false
2 20 20以上なのでtrue true
(trueを返す要素が見つかったのでループはここまで)
(3 ループ回数に含まれない)
(4 ループ回数に含まれない)

また、コールバック関数の処理内容に対してtrueとなる配列の要素がひとつもない場合は、返り値がfalseとなります。

さらに、空の配列に対してはコールバック関数の処理内容にかかわらず、falseを返します。

every()

false を返す要素が見つかるまで、要素に対して一度ずつコールバック関数を実行します。
false を返す要素が見つかるとfalse を返し、ループが終わります。

使用例

行われていること

ループ回数 elmの中身 処理内容
(elm >= 25かチェックする)
返り値(return)
1 40 25以上なのでtrue true
2 30 25以上なのでtrue true
3 20 25以上ではないのでfalse false
(falseを返す要素が見つかったのでループはここまで)
(4 ループ回数に含まれない)

また、コールバック関数の処理内容に対してfalseとなる配列の要素がひとつもない場合は、返り値がtrueとなります。

さらに、空の配列に対してはコールバック関数の内容にかかわらず、trueを返します。

find()

true を返す要素が見つかるまで、要素に対して一度ずつ関数を実行します。
trueになった時点で、それに該当する値を返します。

使用例

行われていること

ループ回数 elmの中身 処理内容
(elm % 20 === 0かチェックする)
返り値(hoge)
1 10 20で割った余りは0ではないのでfalse undefined
2 20 20で割った余りは0なのでtrue 20
(trueを返す要素が見つかったのでループはここまで)
(3 ループ回数に含まれない)
(4 ループ回数に含まれない)

reduce()

要素に対して一度ずつコールバック関数を繰り返し、コールバック関数が最後にreturnした値がreduce全体の返り値になります。

reduceはちょっと難しいメソッドになります。

コールバック関数の引数は最大4つありますが、
currentValue,currentIndex,arrayに関しては任意なので設定しなくてもOKです。

コールバック関数の引数

  • 1.accumulator(必須)

    コールバック関数の返り値が蓄積されていく。
    初回のループでは、initialValueがが設定されている場合はその値が設定されるが、そうでない場合は配列の0番目の要素が設定される。

  • 2. currentValue(必須)

    現在処理されている配列の要素

  • 3. currentIndex(任意)

    現在処理されている配列要素のインデックス。
    initialValueが設定されている場合はインデックス0から、そうでない場合は1から始まる。

  • 3. array(任意)

    reduce() が呼び出された配列。

そして、reduce()の第二引数にinitialValueを設定することができます。

上でも書きましたが、initialValueが設定されていない場合、
reduce()は最初の要素を飛ばしてインデックス 1 から実行されます。
initialValue が指定されていたらインデックス 0 から処理が開始します。

よって、initialValueを設定しておいたほうが意図した挙動となるため、通常は設定したほうが良いでしょう。

使用例

行われていること

ループ回数 accumulatorの中身
(returnしたaccumulatorの値が入る)
currentValueの中身 currentIndexの中身 処理内容
(オブジェクトにキーと値の追加をする)
返り値(acc)
1 {}(第二引数の空のオブジェクト) 10 0 acc[‘number0’] = 10 {number0:10}
2 {number0:10} 20 1 acc[‘number1’] = 20 {number0:10 , number1:20}
3 {number0:10 , number1:20} 30 2 acc[‘number2’] = 30 {number0:10 , number1:20 , number2:30}

reduce()はプログラミング初心者にとってはなかなか難易度が高いコードですが、先ほどご紹介したJS Binなどのツールを使って理解を深めてほしいと思います。

【参考】
MDN reduce()
reduce()はArrayにて最強……おぼえておけ。

おまけ

上記のメソッドは単体で使用することもありますが、合わせて使う時も出てきます。
ここではその一例を紹介します。

使用例

説明

elmsの構造としては、
配列の中に、objectが2つあり(aプロパティが2つ)、そのプロパティに対する値が配列となっています。
そして、その配列の中にさらにobjectが2つ存在するといった構造です。

aプロパティまでは同じですが、その中身が異なります。
それは_aプロパティの値が片方は’apple’で、もう片方は’banana’であるという点です。

そこで、_aプロパティの値が’banana’である、object全体を取得したい場合のコードを書きました。

言葉だけだとわかりにくいので図にしました!

実行結果を見るとわかるように、ちゃんと_aプロパティの値がbananaであるobjectだけが取得できていることがわかりますね!

この記事で扱ったメソッドたち

最後に、この記事で扱ったメソッドをもう一度整理しておきましょう。
(各タイトルはページ内リンクになっています)

メソッド 説明
forEach 全ての要素に対してコールバック関数を一度ずつ実行する。

map や filter とは異なり新しい配列は生成しない。

map 全ての要素に対してコールバック関数を一度ずつ実行する。

返り値からなる新しい配列を生成する。

filter 全ての要素に対してコールバック関数を一度ずつ実行する。

返り値で 、true を返した要素からなる新しい配列を生成する。

some true を返す要素が見つかるまで、要素に対して一度ずつコールバック関数を実行する。

true を返す要素が見つかるとtrue を返し、ループが終わる。

every false を返す要素が見つかるまで、
要素に対して一度ずつコールバック関数を実行する。

false を返す要素が見つかるとfalse を返し、ループが終わる。

find true を返す要素が見つかるまで、要素に対して一度ずつコールバック関数を実行する。

trueになった時点で、それに該当する値を返す。

reduce 要素に対して一度ずつコールバック関数を繰り返し、

コールバック関数が最後にreturnした値がreduce全体の返り値になる。

まとめ

今回は、JavaScriptのループメソッドを7つ紹介しました。
正直、この記事を読んだだけでは分からないかと思います。(笑)

重要なのはこの記事を読みながら自分で同じコードを書いてみたり、出力結果を変えてみたりして遊んでみると、新たな疑問や発見があってコードをより深く理解できるようになるのでオススメですよ!

ループ処理は頻繁に使うので、ぜひマスターしてJS脱初心者しましょう!

では!