JavaScript 入門

JavaScript 関数定義

これまでに、変数を使ってデータを保存し、条件分岐で意思決定を行い、ループを使って操作を繰り返す方法を学んできました。

しかし、プログラムが大きくなるにつれて、同じ一連の操作を何度も実行したり、コードをもっと構造化して整理したりする必要が出てきます。そこで登場するのが 関数 (Functions) です。

関数を使用すると、一連のコードをパッケージ化して名前を付け、必要な時にいつでも実行できるようになります。これにより、重複を避けるだけでなく、コードの可読性、理解しやすさ、そしてメンテナンス性が向上します。

関数は、メインプログラムの中にある「ミニプログラム」のようなものであり、それぞれが特定のタスクを完了させるために設計されています。本セクションでは、これら強力な再利用可能コードブロックの定義方法を深く学び、特に 引数 (Parameters) による入力の受け取りと、 戻り値 (Return Values) による出力の提供に焦点を当てます。

1. 関数を定義する

JavaScriptで関数を定義する最も一般的な方法は、関数宣言を使用することです。

これは function キーワードで始まり、次に関数名、括弧 () で囲まれた引数リスト、最後に波括弧 {} で囲まれた実行されるコードが続きます。

基本構文を分解してみましょう:

function functionName(parameter1, parameter2, /* ... */) {
  // 実行されるコード
  // ここが関数本体です
}
  • function: このキーワードは、JavaScriptに対して関数を定義していることを伝えます。
  • functionName: 関数に付ける一意の識別子(名前)です。関数の機能を説明する名前を付けるのがベストプラクティスです(例:calculateSum 合計を計算、displayMessage メッセージを表示、getUserInput ユーザー入力を取得)。
  • parameter1, parameter2...: これらはオプションのプレースホルダーで、関数に渡したい値を受け取るために使用します。関数に入力が必要ない場合でも、空の括弧 () を記述する必要があります。
  • { ... }: 関数本体(ブロック)です。ここに関数が呼び出されたときに実行されるすべてのJavaScriptステートメントを記述します。

関数を定義しただけでは、自動的に実行されることはありません。コードを動かすには、関数を 呼び出し (Call) または 実行 (Invoke) する必要があります。関数の呼び出しは、関数名に括弧 () を付けるだけです。

function sayHello() {
  // この関数は単純にメッセージをプリントします
  console.log("こんにちは、世界!");
}

// コードを実行するために関数を呼び出す
sayHello(); // 出力: こんにちは、世界!
sayHello(); // 出力: こんにちは、世界! (何度でも呼び出し可能です)

このシンプルな例では、sayHello は入力(引数)を受け取らず、明示的な出力(戻り値)も返さない関数であり、単に「世界に挨拶する」というアクションをカプセル化しています。

2. コード再利用の重要性

以前の成績計算機の例を思い出してみましょう。複数の学生の成績を計算する必要がある場合、if/else if ロジックを何度も繰り返し記述しなければなりませんでした。関数を使えば、ロジックを一度だけ書き、それを繰り返し利用できます。

// 関数を使わない場合 (コードの重複)
let student1Score = 85;
if (student1Score >= 90) {
  console.log("学生1の成績: A");
} else if (student1Score >= 80) {
  console.log("学生1の成績: B");
} else {
  console.log("学生1の成績: C");
}

let student2Score = 72;
if (student2Score >= 90) {
  console.log("学生2の成績: A");
} else if (student2Score >= 80) {
  console.log("学生2の成績: B");
} else {
  console.log("学生2の成績: C");
}

// 関数を使用する場合 (再利用可能)
function displayGrade(score) {
  if (score >= 90) {
    console.log("成績: A");
  } else if (score >= 80) {
    console.log("成绩: B");
  } else {
    console.log("成績: C");
  }
}

displayGrade(85); // 出力: 成績: B
displayGrade(72); // 出力: 成績: C
displayGrade(95); // 出力: 成績: A

見ての通り、displayGrade を定義することでコードがクリーンになり、管理が容易になりました。成績の計算ルールを変更する必要がある場合、関数定義の1箇所を修正するだけで済みます。

3. 引数 (Parameters) の理解

引数 (Parameters) は、本質的には関数定義の中にリストアップされた変数です。これらはプレースホルダーとして機能し、関数呼び出し時に渡される値を表します。

実際に渡される具体的な値は 実引数 (Arguments) と呼ばれます。このようにして、関数は特定のデータを関数本体にハードコーディングすることなく、動的に処理することができます。

3.1 引数の定義

関数名の後の括弧 () 内に引数を列挙します。複数の引数がある場合は、カンマで区切ります。

function greet(name) { // 'name' は引数(パラメータ)です
  console.log("こんにちは、" + name + "!");
}

greet 関数において、name は引数です。この関数を呼び出すとき、name に具体的な値を提供します。

3.2 引数値 (Arguments) の受け渡し

関数を呼び出す際、括弧内に提供する値を 実引数 (Arguments) と呼びます。これらの値は関数に渡され、順番に対応する引数に代入されます。

// greet 関数を呼び出し、実引数を渡す
greet("Alice");    // 出力: こんにちは、Alice!
greet("Bob");      // 出力: こんにちは、Bob!

let userName = "Charlie";
greet(userName);   // 出力: こんにちは、Charlie!

ここでは、"Alice""Bob"、そして変数 userName の値("Charlie")がすべて実引数です。greet("Alice") が呼び出されると、文字列 "Alice" がその実行において関数内部の name 引数に代入されます。

3.3 複数の引数を持つ関数

関数は任意の数の引数を持つことができます。

function addNumbers(num1, num2) { // num1 と num2 は引数です
  let sum = num1 + num2;
  console.log("合計は: " + sum);
}

addNumbers(5, 10);   // 出力: 合計は: 15
addNumbers(100, 200); // 出力: 合計は: 300

addNumbers(5, 10) が呼び出されると、その回の呼び出しにおいて num15num210 になります。

3.4 デフォルト引数 (モダン JavaScript)

時には、引数が渡されなかった場合にデフォルトの値を使用したいことがあります。これはモダンJavaScript(ES6以降)の機能であり、関数をより柔軟にします。

function sayGoodbye(name = "ゲスト") { // 'ゲスト' は 'name' のデフォルト値です
  console.log("さようなら、" + name + "!");
}

sayGoodbye("David");  // 出力: さようなら、David!
sayGoodbye();         // 出力: さようなら、ゲスト! (引数がないため、デフォルト値を使用)
sayGoodbye(undefined); // 出力: さようなら、ゲスト! (undefined はデフォルト値をトリガーします)

デフォルト引数は、特定の引数が常に提供されるとは限らないシナリオで非常に便利です。

4. 戻り値 (Return Values) の理解

引数が関数に入力を受け取らせるためのものなら、 戻り値 (Return Values) は関数がその結果を呼び出し元に送り返すためのものです。

これは、計算やデータ処理を主な目的とし、その結果をプログラムの後の工程で使用する関数を作成する際に不可欠です。

4.1 return キーワード

return キーワードは関数内部で使用され、関数が出力すべき値を指定します。JavaScriptが return 文に出会うと、2つのことが起こります:

  1. 関数は 即座に実行を停止 します。関数体内の return 文以降のコードは実行されません。
  2. 指定された値(値が指定されていない場合は undefined)が、関数が呼び出された場所に送り返されます。

addNumbers の例を修正して、合計をプリントするのではなく 返す (return) ようにしてみましょう:

function add(num1, num2) {
  let sum = num1 + num2;
  return sum; // 関数は合計を返します
  console.log("このコードは実行されません!"); // return 以降は到達不能コードです
}

// 返された値を変数に格納する
let result = add(5, 10);
console.log("合計は: " + result); // 出力: 合計は: 15

// 返された値を直接使用する
console.log("別の合計: " + add(100, 200)); // 出力: 別の合計: 300

// 他の計算や条件の中で戻り値を使用できる
let total = add(2, 3) + add(4, 5); // 5 + 9 と同等
console.log("合計の合計: " + total); // 出力: 合計の合計: 14

この例では、add 関数が計算結果を return しています。呼び出し元ではその結果を result という変数に代入したり、他の計算に直接組み込んだりすることができます。

4.2 関数が何も返さない場合は?

関数に明示的な return 文がない場合、あるいは return; とだけ記述されている場合、その関数は暗黙的に undefined を返します。

function doNothing() {
  console.log("ここでは何も返していません!");
}

let returnValue = doNothing();
console.log(returnValue); // 出力: undefined

アクション(ログの出力、外部変数の変更など)を実行するだけで値を返さない関数もありますが、計算結果を 利用 する必要がある場合は、必ず return を使用しなければなりません。

5. 現実世界のメタファー:引数と戻り値

コーヒーメーカー を想像してみてください:

  • 関数 (Function): コーヒーメーカー本体です。その目的は「コーヒーを作ること」です。
  • 引数 (Parameters): 提供する必要がある設定オプションです。例:豆の種類、水の量、濃さの設定など。
  • 実引数 (Arguments): 実際に選択した値です。例:「深煎り豆」、「150mlの水」、「特濃」。
  • 戻り値 (Return Value): 完成した一杯のコーヒーです。コーヒーは、あなたの入力に基づいてマシンが動作した後の 結果 です。

もう一つの例、 レンタカーサービス:

  • 関数: rentCar() (車を借りる)
  • 引数: carType (車種), rentalDays (日数), customerName (顧客名)
  • 実引数: ("SUV", 7, "田中")
  • 戻り値: 予約確認番号とSUVのキー。

6. 実践的な例とデモンストレーション

引数と戻り値を組み合わせて、より実用的で複雑なシナリオを構築してみましょう。

6.1 示例 1:長方形の面積を計算する

この関数は length(縦)と width(横)の2つの引数を受け取り、それらの積を返します。

function calculateRectangleArea(length, width) {
  // 入力バリデーション (第3モジュールの知識に基づいた良い習慣)
  if (length <= 0 || width <= 0) {
    console.warn("長さと幅は正の数である必要があります。");
    return 0; // 無効なサイズに対しては 0 を返す
  }
  const area = length * width;
  return area;
}

let livingRoomArea = calculateRectangleArea(10, 5);
console.log("リビングの面積:", livingRoomArea, "平方単位"); // 出力: 50

let invalidArea = calculateRectangleArea(-2, 5); // 警告が表示される
console.log("無効な面積:", invalidArea);        // 出力: 0

ここでは面積を単に表示するのではなく、プログラムの他の部分(例:必要なペンキの量や床材の計算)で利用できるようにデータを返しています。

6.2 示例 2:偶数判定

この関数は number を受け取り、剰余演算子(%)を使用して偶数かどうかを判断し、true または false を返します。

function isEven(number) {
  // 2で割った余りが0なら偶数
  return number % 2 === 0;
}

console.log("4は偶数?", isEven(4)); // 出力: true
console.log("7は偶数?", isEven(7)); // 出力: false

isEven 関数の戻り値は、if 文の条件の中で直接使用できるため、非常に高い再利用性を持ちます。

6.3 示例 3:パーソナライズされた挨拶文の生成

名前 name と、デフォルト値を持つ敬称 salutation を受け取り、テンプレートリテラルを使用して完全な挨拶文字列を返します。

function generateGreeting(name, salutation = "こんにちは") {
  // テンプレートリテラルで文字列を構築 (第2モジュールの知識)
  return `${salutation}、${name}さん!ご来店ありがとうございます。`;
}

console.log(generateGreeting("マリア")); // 出力: こんにちは、マリアさん!...
console.log(generateGreeting("田中", "おはようございます")); // 出力: おはようございます、田中さん!...