IT・テクノロジー

【オウル先生の基礎講座】Vol.5「関数の使い方をマスターしよう」

progmraming

プログラムを部品化する「関数」の基本を解説!

先生、関数ってなんで必要なの?普通にコードを書いていけばいいんじゃないの?
フォックン
フォックン
いい質問だね、フォックン!関数はプログラミングの鍵となる概念だよ。同じ処理を何度も書かなくて済むし、プログラムが整理されて見やすくなるんだ。それに、テストや修正も簡単になるんだよ😊
オウル先生
オウル先生

関数とは?

関数は、特定の処理をまとめて名前を付けた塊です。料理に例えると、レシピのようなものです。一度定義すれば、何度でも使い回すことができます。

// 関数なしの場合
console.log("太郎さん、こんにちは!");
console.log("花子さん、こんにちは!");
console.log("次郎さん、こんにちは!");

// 関数を使った場合
function greet(name) {
  console.log(`${name}さん、こんにちは!`);
}

greet("太郎");
greet("花子");
greet("次郎");

関数の基本構文

関数宣言(Function Declaration)

function 関数名(引数1, 引数2) {
  // 処理内容
  return 戻り値;  // オプション
}

// 例:2つの数値を足す関数
function add(a, b) {
  return a + b;
}

const result = add(5, 3);
console.log(result); // 8

関数式(Function Expression)

const 関数名 = function(引数1, 引数2) {
  // 処理内容
};

// 例:名前付き関数式
const multiply = function(a, b) {
  return a * b;
};

アロー関数(Arrow Function)

const 関数名 = (引数1, 引数2) => {
  // 処理内容
};

// 例:簡潔な書き方
const square = x => x * x;
const greet = () => console.log("Hello!");
3種類もあるの!?どれを使えばいいの…?
フォックン
フォックン
状況によって使い分けるよ!関数宣言は一番基本的で、どこからでも呼び出せる。関数式は変数に代入するスタイルで、アロー関数は特に簡潔に書けるんだ。最初は関数宣言から始めてみよう!
オウル先生
オウル先生

引数(パラメータ)と戻り値

引数の種類

// 通常の引数
function introduce(name, age) {
  console.log(`私は${name}で、${age}歳です。`);
}

// デフォルト引数(ES6+)
function greet(name = 'ゲスト') {
  console.log(`こんにちは、${name}さん!`);
}
greet(); // こんにちは、ゲストさん!
greet('山田'); // こんにちは、山田さん!

// 可変長引数(Rest Parameters)
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15

戻り値

// 値を返す関数
function calculateTax(price, taxRate) {
  return price * taxRate;
}

// 複数の値を返す(オブジェクトで)
function getDivisionResult(a, b) {
  return {
    quotient: Math.floor(a / b),
    remainder: a % b
  };
}

const result = getDivisionResult(10, 3);
console.log(result.quotient); // 3
console.log(result.remainder); // 1

スコープと変数

// グローバルスコープ
let globalVar = "グローバル変数";

function example() {
  // ローカルスコープ
  let localVar = "ローカル変数";
  
  // グローバル変数にアクセス可能
  console.log(globalVar);
  
  // ローカル変数は関数内のみ
  console.log(localVar);
}

// ブロックスコープ
if (true) {
  let blockVar = "ブロック変数";
  var functionVar = "関数スコープ変数";
}
// console.log(blockVar); // エラー!
console.log(functionVar); // OK(varは関数スコープ)
スコープの理解は重要だよ。変数がどこで使えるかを知ることで、予期せぬバグを防げるんだ。最近はletとconstを使ってブロックスコープを活用するのが主流だね。
オウル先生
オウル先生

実践的な関数パターン

コールバック関数

// 配列処理でよく使われるパターン
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(function(num) {
  return num * 2;
});

// アロー関数で簡潔に
const tripled = numbers.map(num => num * 3);

// カスタムコールバック関数
function processArray(arr, callback) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i]));
  }
  return result;
}

const squared = processArray([1, 2, 3], x => x * x);

即時実行関数(IIFE)

// 即時実行関数パターン
(function() {
  console.log("すぐに実行される");
})();

// プライベート変数の作成
const counter = (function() {
  let count = 0;
  return {
    increment: () => ++count,
    decrement: () => --count,
    getValue: () => count
  };
})();

console.log(counter.getValue()); // 0
counter.increment();
console.log(counter.getValue()); // 1

高度な関数テクニック

クロージャ

function createMultiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

再帰関数

// 階乗計算
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

// フィボナッチ数列
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}
再帰って難しそう…でも便利そうだね!
フォックン
フォックン
再帰は最初は理解するのが難しいけど、一度マスターすると強力なツールになるよ。ファイルシステムの探索や木構造の処理など、階層的なデータにはピッタリなんだ。ただし、無限ループにならないよう注意が必要だね。
オウル先生
オウル先生

関数のベストプラクティス

1. 単一責任の原則

// 悪い例:複数の責任を持つ関数
function processUserDataAndSendEmail(userData) {
  // ユーザーデータの処理
  const processedData = validateAndFormatData(userData);
  
  // メール送信
  sendEmail(processedData.email, "Welcome!");
  
  return processedData;
}

// 良い例:責任を分けた関数
function processUserData(userData) {
  return validateAndFormatData(userData);
}

function sendWelcomeEmail(email) {
  sendEmail(email, "Welcome!");
}

2. 純粋関数を心がける

// 非純粋関数(外部状態に依存)
let tax = 0.08;
function calculateTotal(price) {
  return price * (1 + tax);
}

// 純粋関数(副作用なし)
function calculateTotalPure(price, taxRate) {
  return price * (1 + taxRate);
}

3. 意味のある名前を付ける

// 悪い例
function proc(a, b) { return a + b; }

// 良い例
function calculateTotal(price, tax) { return price + tax; }

実践チャレンジ

以下の問題に挑戦してみましょう:

問題1: BMI(体格指数)を計算する関数を作成してください。

  • BMI = 体重(kg) ÷ (身長(m) × 身長(m))

問題2: 文字列を逆さにする関数を作成してください。

  • 例:”hello” → “olleh”

問題3: 配列内の偶数だけを抽出して2倍にする関数を作成してください。

解答例を表示
// 問題1の解答
function calculateBMI(weight, height) {
  const bmi = weight / (height * height);
  return Math.round(bmi * 10) / 10; // 小数点1桁まで
}

// 問題2の解答
function reverseString(str) {
  return str.split('').reverse().join('');
}

// アロー関数版
const reverseStringArrow = str => str.split('').reverse().join('');

// 問題3の解答
function filterAndDoubleEvens(numbers) {
  return numbers
    .filter(num => num % 2 === 0)
    .map(num => num * 2);
}

// 使用例
console.log(calculateBMI(70, 1.75)); // 22.9
console.log(reverseString("programming")); // "gnimargorp"
console.log(filterAndDoubleEvens([1, 2, 3, 4, 5, 6])); // [4, 8, 12]

モダンな関数パターン

分割代入(Destructuring)

// オブジェクトの分割代入
function createUser({ name, age, email }) {
  return {
    name,
    age,
    email,
    createdAt: new Date()
  };
}

const user = createUser({ name: "Alice", age: 30, email: "alice@example.com" });

// 配列の分割代入
function getMinMax(...numbers) {
  return [Math.min(...numbers), Math.max(...numbers)];
}

const [min, max] = getMinMax(1, 5, 3, 9, 2);

テンプレートリテラル

function formatDate(date, format = 'YYYY-MM-DD') {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  
  return `${year}-${month}-${day}`;
}

まとめ

関数はプログラミングの基礎中の基礎です。適切に使用することで:

  1. コードの再利用性が向上
  2. 保守性が高まる
  3. テストが容易になる
  4. コードの可読性が向上

重要なポイント:

  • 単一責任の原則を守る
  • 意味のある名前を付ける
  • 副作用を最小限にする
  • 適切なスコープ管理
関数の使い方がよく分かったよ!これでコードがスッキリしそう!
フォックン
フォックン
素晴らしい!関数を上手に使えるようになると、プログラミングの楽しさが倍増するよ。次回はオブジェクトについて学んでいくね。オブジェクトを使えば、さらに複雑なデータを上手く扱えるようになるよ!
オウル先生
オウル先生

次回予告

Vol.6では「オブジェクトの基本を学ぼう」をテーマに、JavaScriptのオブジェクト指向プログラミングの基礎を解説します。お楽しみに! 🚀

続けて読む
【オウル先生の基礎講座】Vol.6「オブジェクトの基本を学ぼう」
【オウル先生の基礎講座】Vol.6「オブジェクトの基本を学ぼう」
あわせて読みたい
【簡単】モチベーションを維持する5つの方法|やる気が続かない悩みを解決!
【簡単】モチベーションを維持する5つの方法|やる気が続かない悩みを解決!
あわせて読みたい
エラーこそ成長のチャンス!初心者が問題解決能力を爆上げするテクニック
エラーこそ成長のチャンス!初心者が問題解決能力を爆上げするテクニック
ABOUT ME
アウル先生&フォックン
アウル先生&フォックン
ブログライター
オウル先生 フォックンが運営する未経験からのプログラミング上達ガイド! プログラミング学習に興味があるけど、 「どのスクールを選べばいいか分からない…」 「自分に合った学習方法が知りたい…」 「本当にエンジニアになれるか不安…」 そんな悩みをお持ちのあなたへ。 オウル先生とフォックンが、プログラミングスクール選びから学習方法、キャリア形成まで、丁寧にサポートします! 豊富な情報と分かりやすい解説で、あなたのプログラミング学習を成功へと導きます。
記事URLをコピーしました