関数とは?

Updated
2021/8/8 9:30
Author
Jumpei IkegamiJumpei Ikegami
order
5

プログラミングにおける関数とは?

次の例にあるshortenString関数は、文字列を渡したときその長さが20文字より大きかったら21文字目以降を'...'で省略して返してくれる関数です。
JavaScript
この例のように、関数には次のような特徴があります。
  • 関数で複数行の処理をまとめられる
  • 関数には名前をつけられる
  • 関数の名前を使って後から呼び出せる
  • 呼び出し時、関数にはデータを渡すことができる(「引数」を渡すという)
  • 呼び出し時、関数からデータを受け取ることができる(「戻り値」や「返り値」という)
関数とは、プログラミング言語において、処理に名前をつけて扱うための手段です。関数を使うことには、主に次の2つの目的があります。
  1. 処理に名前をつけてわかりやすくする
  1. 同じ処理を別々の場所で繰り返し使い回せるようにする

関数を使う必要がない場面でも、使うメリットはある

この記事の冒頭に記載したプログラムでは、関数shortenStringを使っていました。
JavaScript
このプログラムは、関数を使わずに次のように書いても同じ結果になります。
JavaScript
このように、あえて関数を使わなくても期待する動作を実現するプログラムを書ける場面はたくさんあります。特に、このような短いプログラムであれば、関数を使って書いた方が冗長になってしまいます。
しかし、まとまった処理はなるべく関数として切り出しておいた方が幸せになることが多いです。
さて、次のリファレンスを先に読んだ賢明な読者の方であれば、ここまでの説明が変数の説明に酷似していることに気付いたかもしれません。
変数とは?2021/6/20 6:082021/8/8 9:18
 
細かく見ると様々な違いはありますが、変数は「データ」に名前をつけるものであったのに対して、関数は「処理」に名前をつけるものである、という理解ができます。変数を使うことで得られるのと同様のメリットを、関数を使うことでも得ることができます。(ここで、「変数とは?」をまだ読んでいない人は先に読むことをおすすめします。)
変数を使うメリットとして、「可読性」と「保守性」の説明をしました。関数についても、処理に適した名前をつけることで「何を目的にした処理なのか」が一目でわかるようになります。また、何度も同様の処理をする場合であっても、それを関数化して繰り返し呼び出していれば、関数の中身を変更するだけで全ての処理に対して変更を適用することができます。

JavaScriptにおける関数の使い方

ここからは、JavaScriptにおける関数の使い方について説明します。

既にある関数を呼び出す

予め定義されている関数を呼び出す場合、次のようにします。
JavaScript
何かの「戻り値」を返してくれる関数であれば、その結果を変数に格納することもできます。
JavaScript
次の例は、記事冒頭で紹介した関数shortenString()を呼び出す例です。
JavaScript
引数にurlを渡し、加工後のurlを戻り値として受け取って再び変数urlに格納し直しています。
なお、オブジェクトのプロパティとして定義された関数を特別に「メソッド」と呼びます。
JavaScriptでは自分で関数を作らなくても、よく使う関数をJS側が予め用意してくれています。たとえば、次のリファレンスで紹介した次のようなメソッドも、文字列に対して呼び出せるように予め用意された、便利な関数たちです。
JavaScript
文字列を加工する方法2021/6/20 6:082021/8/8 9:33
 

関数を新しく定義する

次のように、関数を自分で新しく定義することもできます。
JavaScript
記事冒頭の例でも、次のような関数shortenStringを定義していました。
JavaScript
関数を定義する段階では、引数に実際どのような値が渡されるかわかりません。そのため、関数定義では引数の部分を変数で記述します。この変数は、通常の変数と同じく自由に名前をつけることができます。ちなみに、仮で引数の代わりに置く変数のことを「仮引数」と呼びます。仮引数は、カンマ区切りで複数指定することもできます。
JavaScript
戻り値を返す関数を作る場合は、returnの後に実際に返したい値を記述します。関数中でreturnが呼ばれると、その時点で関数が終了します。returnより下の行に処理を書いていても、その行は実行されることはありません。
JavaScript

名も無き関数

変数と違って、JavaScriptの関数は必ずしも名前をつける必要はありません。次のようなケースでは、「無名関数」と呼ばれる名も無き関数もよく使われます。
無名関数が使われる一番のケースは、関数の引数として関数を渡す場合です。何を言っているかわからないと思いますが、ここがJavaScriptを理解する上で避けては通れない要所です。
「文字列を加工する方法」の「文字列を配列に変換する」の項で、配列を扱う次のようなプログラムを紹介しました。
JavaScript
ここでは、forEach()というメソッドを使っています。forEach()は次のように配列に対して呼ぶことができ、引数に関数を渡して使います。
JavaScript
forEach()の機能は、「配列の要素を1つずつ取り出して同じ処理をする」というものです。しかし、forEach()を使うときの目的に応じて、どんな処理をするかというのは毎回異なります。そこで、この「どんな処理をするのか」を関数として定義し、forEach()に教えてあげることができます。これが、「関数の引数として関数を渡す」の代表例です。なお、forEach()に渡した関数は、forEachの機能によって、配列の要素数と同じ回数だけ繰り返し呼び出されます。そのとき、渡した関数に引数として、配列の要素が順々に渡されます。上記の例でいえば、1回目の呼び出しでは引数qには文字列'foo'が、2回目は文字列'bar'が、3回目は文字列'baz'が渡されます。これにより、「配列の要素を1つずつ取り出して」処理するというforEach()の機能が実現できます。
もちろん、次のように別で名前をつけて定義した関数を引数に渡すこともできます。
JavaScript
ここまでが、「関数の引数として関数を渡す場合」の説明でした。特に、配列を操作するメソッドでよく使われます。
「無名関数」を使うもう1つのケースは、ブックマークレットです。
たとえば、チュートリアルで次のようなブックマークレットを紹介しました。
JavaScript
2. ワンクリックでAmazonの商品名をGoogle検索するボタンを作る2021/6/20 4:332021/8/8 8:00
 
冒頭のjavascript:はブックマークレットに独特の記法で、「ここからjavascriptを書きますよ」ということを意味します。実際のJSの処理は、その後の(function...からです。
括弧が多くて吐き気がするかもしれませんが、注意深く見ていきましょう。すると、ここでは名も無き関数を定義し全体を()で括った上で、さらに末尾の()を使ってその名も無き関数を即時に実行していることがわかります。
JavaScript
このように、ブックマークレットでは無名関数をすぐに実行する形で全体の処理が記述されることが多いです。ちなみに、定義した瞬間に関数を実行することを「即時実行」と呼びます。ここでは、「ブックマークレットでは無名関数を即時実行する慣習なのだなあ」という理解で大丈夫です。なぜこのようなことをするか気になる方は、ぜひ「javascript 無名関数 即時実行 スコープ」でググってみてください。
以上が無名関数の話でした。これらの説明はかなり難しいので、全て理解できなくても全く問題ありません。JSを使っていく中で慣れていきましょう。

もっと詳しく知りたい方へ