JavaScriptで「関数から複数の値を返す」をやさしく理解する
最初に覚えてほしいのは、JavaScriptの関数は基本的に「戻り値は1つだけ」ということです。でも工夫すれば「複数の情報」をまとめて返せます。ここでは3つの方法を、例題つきでわかりやすく説明します。
配列でまとめて返す
配列は、値を順番に並べられる「箱」です。これに複数の値を入れて、まとめて返します。
- イメージ: 「1つの荷物に2つの品物を入れて渡す」
- 向いている場面: 値の意味が明確で、順番が決まっているとき(例: 最大値、最小値)
// 3つの数の「最大値」と「最小値」を返す
function maxAndMin(a, b, c) {
const max = Math.max(a, b, c);
const min = Math.min(a, b, c);
return [max, min]; // 配列で返す
}
// 受け取り方その1:インデックスで取り出す
const result = maxAndMin(10, 7, 14);
console.log(result[0]); // 14 (最大値)
console.log(result[1]); // 7 (最小値)
JavaScript- 注意点: 配列は「位置」で意味が決まるので、0番目が何で、1番目が何なのかを覚えておく必要があります。
分割代入で読みやすくする
配列の各要素を、わかりやすい変数名に「ばらして」受け取る方法です。読みやすさが一気に上がります。
- イメージ: 「箱から取り出して、名前のついた引き出しにしまう」
- メリット: インデックス番号を覚えなくて良い、コードの意図が伝わりやすい
// 分割代入で受け取る
const [maxValue, minValue] = maxAndMin(10, 7, 14);
console.log(maxValue); // 14
console.log(minValue); // 7
JavaScript- コツ: 変数名を「意味が伝わる名前」にすると、後で見返したときに迷いません。
オブジェクトで「名前つき」で返す
配列は「順番」が大事。一方、オブジェクトは「名前」で意味が伝わります。初心者にはこちらのほうが安全・読みやすい場面が多いです。
- イメージ: 「ラベルつきファイルで渡す」
- 向いている場面: 値の種類が増える、順番に依存したくない、後から項目が増減する可能性がある
// 合計・平均・件数を返す関数
function summarize(numbers) {
const count = numbers.length;
const sum = numbers.reduce((acc, n) => acc + n, 0);
const avg = count === 0 ? 0 : sum / count;
return { sum, avg, count }; // オブジェクトで返す
}
// 受け取り方その1:ドットで取り出す
const stats = summarize([10, 20, 30]);
console.log(stats.sum); // 60
console.log(stats.avg); // 20
console.log(stats.count); // 3
// 受け取り方その2:オブジェクトの分割代入
const { sum, avg, count } = summarize([10, 20, 30]);
console.log(sum, avg, count); // 60 20 3
JavaScript- メリット: 順番を気にしなくて良い/今後項目が増えてもコードが壊れにくい
- 小技: 返す側でプロパティ名を、受け取る側で変数名を変えることもできます
例:const { avg: average } = summarize([10,20,30]);
どれを使えばいい?
- 短く単純(意味が明確・順序固定): 配列+分割代入
例:[max, min] - 項目に名前がほしい/今後増えるかも: オブジェクト
例:{ sum, avg, count }
直感で迷ったら「オブジェクト」を選ぶと安全です。コードの意図が伝わりやすく、保守しやすいからです。
例題で練習
例題1:時・分・秒に分解して返す(配列版)
- 目的: 秒数から「時・分・秒」を計算して返す
- ポイント: 順番が固定なので配列でもOK
function toHMS(totalSeconds) {
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return [hours, minutes, seconds];
}
const [h, m, s] = toHMS(3665);
console.log(`${h}時間${m}分${s}秒`); // 1時間1分5秒
JavaScript例題2:ログイン結果を返す(オブジェクト版)
- 目的: 成功・失敗の両方に対応する複数情報を返す
- ポイント: 名前つきで意味が明確、項目が増えても安心
function login(username, password) {
const ok = username === "user" && password === "pass";
if (ok) {
return {
success: true,
userId: 123,
message: "ログイン成功",
};
} else {
return {
success: false,
errorCode: "INVALID_CREDENTIALS",
message: "ユーザー名またはパスワードが違います",
};
}
}
const result = login("user", "wrong");
if (result.success) {
console.log(`ID: ${result.userId}`);
} else {
console.log(`エラー: ${result.errorCode} - ${result.message}`);
}
JavaScript例題3:計算とエラーをまとめて返す(配列+オブジェクト応用)
- 目的: 計算結果と、失敗時のエラー情報を一緒に
- ポイント: 返すものが「成功/失敗」で形が変わるなら、オブジェクトが扱いやすい
function safeDivide(a, b) {
if (b === 0) {
return { ok: false, error: "ゼロでは割れません" };
}
return { ok: true, value: a / b };
}
const r1 = safeDivide(10, 2);
const r2 = safeDivide(10, 0);
console.log(r1.ok ? r1.value : r1.error); // 5
console.log(r2.ok ? r2.value : r2.error); // ゼロでは割れません
JavaScriptよくあるつまずきポイント
- インデックスの勘違い: 配列は0から始まる(最初の要素は
[0])。 - 長い配列の意味不明化: 配列に5個も6個も詰めると何が何だか分からなくなる。そんなときはオブジェクトに。
- 分割代入の順番違い: 配列の分割は「左から順番」。オブジェクトの分割は「名前でマッチ」。
まとめ
- 戻り値は1つだけ → 複数の値は「まとめて返す」
- 短く固定の情報 → 配列+分割代入
- 意味を明確にしたい/今後変わりそう → オブジェクト
- 読みやすさ優先で変数名にこだわる(分割代入で名前をつけて受け取る)
ミニ練習問題(答えは自分で動かして確認)
- 問題1: 文字列の配列を受け取り、「最初の要素」と「最後の要素」を返す関数を配列で作る
例:firstAndLast(["a", "b", "c"]) // ["a", "c"] - 問題2: 数値配列を受け取り、「合計」「平均」「最大」「最小」をオブジェクトで返す関数を作る
- 問題3: 日付文字列
YYYY-MM-DDを受け取り、{ year, month, day }を返す関数を作る(split("-")を使う)
解答と解説
問題1
文字列の配列を受け取り、「最初の要素」と「最後の要素」を返す関数を配列で作る
解答例
function firstAndLast(arr) {
const first = arr[0]; // 最初の要素(インデックス0)
const last = arr[arr.length - 1]; // 最後の要素(配列の長さ - 1)
return [first, last]; // 配列で返す
}
// 実行例
const [first, last] = firstAndLast(["a", "b", "c"]);
console.log(first); // "a"
console.log(last); // "c"
JavaScript解説
- 配列の最初の要素は
arr[0]で取り出せます。 - 最後の要素は「配列の長さ – 1」の位置にあるので
arr[arr.length - 1]。 - 戻り値を
[first, last]と配列にまとめることで、2つの値を一度に返せます。 - 受け取るときは分割代入を使うと読みやすいです。
問題2
数値配列を受け取り、「合計」「平均」「最大」「最小」をオブジェクトで返す関数を作る
解答例
function analyzeNumbers(numbers) {
const sum = numbers.reduce((acc, n) => acc + n, 0); // 合計
const avg = numbers.length > 0 ? sum / numbers.length : 0; // 平均
const max = Math.max(...numbers); // 最大値
const min = Math.min(...numbers); // 最小値
return { sum, avg, max, min }; // オブジェクトで返す
}
// 実行例
const { sum, avg, max, min } = analyzeNumbers([10, 20, 30, 40]);
console.log(sum); // 100
console.log(avg); // 25
console.log(max); // 40
console.log(min); // 10
JavaScript解説
reduceを使うと配列の合計を簡単に計算できます。- 平均は「合計 ÷ 要素数」。
- 最大値・最小値は
Math.max(...配列)/Math.min(...配列)で求められます。 - オブジェクトで返すことで「sum」「avg」など名前で意味が分かるようになります。
問題3
日付文字列 YYYY-MM-DD を受け取り、{ year, month, day } を返す関数を作る
解答例
function parseDate(dateStr) {
const parts = dateStr.split("-"); // ["2025", "10", "28"]
const year = parts[0];
const month = parts[1];
const day = parts[2];
return { year, month, day }; // オブジェクトで返す
}
// 実行例
const { year, month, day } = parseDate("2025-10-28");
console.log(year); // "2025"
console.log(month); // "10"
console.log(day); // "28"
JavaScript解説
split("-")で文字列を「-」ごとに分割して配列にします。- 配列の0番目が年、1番目が月、2番目が日。
- オブジェクトで返すことで「year」「month」「day」と名前で扱えるので分かりやすいです。
まとめ
- 配列で返す → 値の順番が決まっているとき(例: 最初と最後)
- オブジェクトで返す → 値に名前をつけたいとき(例: 合計・平均・最大・最小、日付の要素)
