第10話:関数
目次
マンガ
マンガ台詞
説明
この章では、『関数』について学びます。プログラムを書いていると、次第に行数が増えて、どこに何を書いているのか見づらくなってきます。そして、同じ処理を、何度も書かなければならなくなってきます。そういった時に利用するのが『関数』です。
『関数』は、何度も行う処理を、一度だけ書いて済ませるプログラムの書き方です。この方法を使えば、プログラムをいくつかの部品に分けて、組み立てるようにしてプログラムを書くことができます。
これは、自動車などの工業製品を作る手法と同じです。タイヤ、ハンドル、エンジン、ブレーキなどをばらばらに作り、最後に組み立てて完成させる。プログラムでも同じように、データを初期化する『関数』、データを加工する『関数』、画面に結果を表示させる『関数』などのように部品分けをして作り、それらの『関数』を組み合わせることで、プログラムを完成させることができます。
このような方法で『関数』を利用すると、プログラムの再利用性も向上します。以前書いたプログラムから、『関数』だけを持ってきて、新しいプログラム内で利用するといったことも可能になります。
それでは以下、『関数』について説明していきます。
『関数』の基本
『関数』は、以下の方法で作れます。
function 関数名(引数) { 内部処理 return 戻り値; }
実際に、この書式で『関数』を作ってみましょう。
function han(no) { var res = no / 2; return res; }
以下、このプログラムを元に、『関数』の構造について解説していきます。
『関数名』『引数』
『han』というのが『関数名』になります。『han』のあとの括弧内に書かれた『no』が、『引数』(ひきすう)と呼ばれる変数になります。『引数』は、内部処理を行う際に、外部から値を受け取るための変数です。
『引数』を書く括弧の中には、変数名を書きます。引数が必要ないのなら、何も書かなくても構いません。『引数』を複数使いたい場合は『han(no1, no2)』のように『,』(カンマ)で区切って並べて書きます。宣言した『引数』は、『関数』内でのみ有効です。
『内部処理』
続く『var res = no / 2;』というのが、内部処理になります。先ほど『引数』として宣言した『no』が計算式中で利用されているのが分かります。この内部処理は、ここでは1行しか書いていませんが、数行にわたって書くこともできます。
『return 戻り値』
最後の行の『return res;』については、少し詳しく説明します。『return』は、「ここで『関数』を終了する」という宣言です。『関数』内で『return』の書かれた行が実行されると、その場所で『関数』の処理が終了します。『関数』が終了すると、その『関数』が呼び出された場所まで処理が戻ります。
『関数』は、『{~}』の末尾まで来るか、『return』の行まで来ると、処理を終えて、呼び出された場所に戻ります。『関数』は、プログラムのどこに書いても構いません。呼び出される場所の前に書いてもよいですし、後に書いてもよいです。
『return』の後には、『関数』の『戻り値』を設定することができます。上記のプログラムでは、『戻り値』として『res』の値を設定しています。そのため、『関数』の結果として『res』の値が、呼び出された場所に戻ります。
『関数』の利用
作成した『関数』は、以下のように利用できます。
var kekka = han(16);
関数『han』を、引数『16』で呼び出しています。関数『han』の内部処理は『16÷2』で、戻り値は『8』となります。この『戻り値』は、『han(16)』という場所に戻されます。結果として、変数『kekka』には『8』という値が入ります。
また、『関数』は、変数のように、式の中に利用することもできます。
var kekka = han(16) * 2;
この場合、関数『han』の結果は『8』。その数字に『2』を掛けた値が、変数『kekka』に入ります。この場合の変数『kekka』の値は16になります。
以下、中級者以上向け。
マンガ中のプログラムの解説
それでは、もう少し長い処理を見てみましょう。マンガで登場したプログラムを元にして、解説を行っていきます。
まず最初にプログラムを書き、その後、処理順番に並べ変えた内容を示します。
var mojiretu; // 変数の初期化 // 【関数呼び出し】 // 『関数』の『戻り値』を、変数『mojiretu』に入れる mojiretu = getMojiretu("足立", 65); alert(mojiretu); // アラート表示 // 【関数】(呼び出されるまで実行されない) // 第1『引数』を、変数『namae』に入れて受け取る // 第2『引数』を、変数『tennsuu』に入れて受け取る function getMojiretu(namae, tennsuu) { var result = namae + "の点数は" + tennsuu + "です"; return result; // 『戻り値』(関数の結果)を戻す } // 【関数呼び出し】 // 『関数』の『戻り値』を、変数『mojiretu』に入れる mojiretu = getMojiretu("木村", 43); alert(mojiretu); // アラート表示
以下、処理順番に並べ替えたものです。関数『getMojiretu』内の変数には青文字で、中身の値を書いておきます。
var mojiretu; // 変数の初期化 mojiretu = getMojiretu("足立", 65);function getMojiretu(namae"足立", tennsuu65) { var result = namae"足立" + "の点数は" + tennsuu65 + "です"; return result"足立の点数は65です"; // 『戻り値』(関数の結果)を戻す }alert(mojiretu); // アラート表示『足立の点数は65です』 mojiretu = getMojiretu("木村", 43);function getMojiretu(namae"木村", tennsuu43) { var result = namae"木村" + "の点数は" + tennsuu43 + "です"; return result"木村の点数は43です"; // 『戻り値』(関数の結果)を戻す }alert(mojiretu); // アラート表示『木村の点数は43です』
それでは以下、さらに詳しく『関数』についてみていきましょう。
『関数』のいろいろな作り方
『関数』は、以下の方法で作れると紹介しました。
function 関数名(引数) { 内部処理 return 戻り値; }
『関数』の作り方には、他にもいくつかの種類があります。
たとえば、『引数』を持たない『関数』は、以下のように書きます。
function 関数名() { 内部処理 return 戻り値; }
また、『return』に何も値を指定しなかった場合は、『戻り値』を戻さない『関数』になります。
function 関数名(引数) { 内部処理 return; }
『戻り値』を戻さない『関数』ならば、『return』自体を省略することもできます。
function 関数名(引数) { 内部処理 }
『引数』も『戻り値』もない『関数』も作れます。
function 関数名() { 内部処理 }
少し複雑な『関数』の実例
『return』を使った『関数』の途中終了を利用して、少し複雑な『関数』を作ってみます。以下のように、『引数』の値によって、処理を分岐させれば、より有用な『関数』を作成することができます。また、『引数』が想定内の値かどうかをチェックすることで、エラーを防ぐこともできます。
var kekka1 = menseki(0, 10); // 関数『menseki』を呼び出し var kekka2 = menseki(5, 10); // 関数『menseki』を呼び出し var kekka3 = menseki(10, 10); // 関数『menseki』を呼び出し document.write(kekka1 + "<br>"); document.write(kekka2 + "<br>"); document.write(kekka3 + "<br>"); function menseki(width, height) { // 『width』(横幅)を引数1として取得 // 『height』(高さ)を引数2として取得 if ((width <= 0) || (height <= 0)) { // 横幅か高さが0以下なら、面積は求められないので終了 return "error!"; } var res = width * height; return res; // 計算結果を戻して終了 }
【結果】
error! 50 100
『if ((width <= 0) || (height <= 0))』として、横幅と高さの値が『0以下の数』にならないように確認しています。そして、どちらかが『0以下の数』だった場合は、『error!』という文字列を、戻り値として戻すようにしています。
このように処理を分岐させることで、複雑な『関数』を作ることができます。
『再帰関数』
以下、少し高度なことを説明します。
『関数』には、『再帰関数』と呼ばれるものがあります。『再帰関数』とは、『関数』から『それ自身を呼び出す』関数のことです。
以下、例を示します。
// 再帰関数を呼び出し saiki(0, 12); // 再帰関数 function saiki(no, max) { // 『no』(再帰回数)を引数1として取得 // 『max』(終了条件の値)を引数2として取得 // 終了条件を満たせば終了 if (no >= max) return; // グラフの作成 var str = ""; for (var i = 0; i < no; i ++) { for (var j = 0; j <= i; j ++) { str += "+"; } } document.write(str + no + "<br>"); // 再び自分自身を呼び出す saiki(no + 1, max); }
【結果】
0 +1 +++2 ++++++3 ++++++++++4 +++++++++++++++5 +++++++++++++++++++++6 ++++++++++++++++++++++++++++7 ++++++++++++++++++++++++++++++++++++8 +++++++++++++++++++++++++++++++++++++++++++++9 +++++++++++++++++++++++++++++++++++++++++++++++++++++++10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++11
『再帰関数』は、終了条件を正しく設定していないと、『無限ループ』(無限に続いて終わらない処理)になることがあります。気を付けてください。
サンプルの入手
以下は、今回出てきたサンプルです。
ZIPでまとめてダウンロード (右クリックから保存してください)
『sample1.html』(処理の順番)を表示
『sample2.html』(少し複雑な関数の実例)を表示
『sample3.html』(再帰関数)を表示
プログラムの中身を見たい場合は、それぞれのHTMLファイルをブラウザで開いたあと、右クリックをして『ソースの表示』を選択してください。
メモ帳で、ファイルの中身を見ることができます。