JavaScript | 関数から複数の値を返す方法

JavaScript JavaScript
スポンサーリンク

JavaScript の関数は return で値をひとつ返しますが、実際には配列やオブジェクトにまとめて返すことで「複数」を返すことができます。返した後は「配列の添え字」や「分割代入(destructuring)」、あるいはオブジェクトのプロパティ名で取り出します。


1. まずは「配列で返す」基本パターン

例題:3つの数の最大値と最小値を返す関数

function maxAndMin(a, b, c) {
  const maxNum = Math.max(a, b, c);
  const minNum = Math.min(a, b, c);
  return [maxNum, minNum]; // 配列にして返す
}
JavaScript

呼び出し方(そのまま配列を受け取る)

const result = maxAndMin(10, 7, 14);
console.log(result[0]); // 14  (配列の0番目が最大値)
console.log(result[1]); // 7   (配列の1番目が最小値)
JavaScript

解説

  • return [maxNum, minNum] は「配列を一つ返している」だけです。配列の中に2つの値が入っているので、見た目上は複数値を返しているように扱えます。

2. 分割代入(配列のdestructuring)でわかりやすく取り出す

配列の何番目かを意識して result[0] とするより、意味のある変数名に直接入れられるとコードが読みやすくなります。

const [maxValue, minValue] = maxAndMin(10, 7, 14);
console.log("Max =", maxValue); // Max = 14
console.log("Min =", minValue); // Min = 7
JavaScript

ポイント

  • 左側 [maxValue, minValue] と返ってくる配列の順番(0番目=max、1番目=min)が一致している必要があります。
  • 順番を間違えると値が入れ替わるので注意。

3. 配列で返す時の注意点(落とし穴)

  • 順序依存:返す順番を変えると呼び出し側も変えないといけない。大きなチーム開発ではミスの元。
  • 意味が直感的でないresult[0] が何なのか、名前だけ見てもわからない。
  • 要素が足りない場合:返される配列が想定より短いと undefined になる。

4. オブジェクトで返す(名前付きで返す) — より安全で読みやすい

配列の順序に依存したくない場合は、オブジェクトでプロパティ名を付けて返すと読みやすく安全です。

function maxAndMinObj(a, b, c) {
  return { max: Math.max(a, b, c), min: Math.min(a, b, c) };
}

const { max, min } = maxAndMinObj(10, 7, 14);
console.log("Max =", max); // Max = 14
console.log("Min =", min); // Min = 7
JavaScript

メリット

  • プロパティ名(max, min)で値を取り出すので何が入っているかが明確
  • 順序を気にしなくて良い({min, max}の順序で返しても取り出し方は同じ)。

5. 実用例:ユーザー名と年齢を返す関数

function getUserData() {
  // たとえばAPIからとってきた想定
  const name = "Taro";
  const age = 28;
  return { name, age }; // オブジェクトでまとめて返す(プロパティ名がそのまま使える)
}

const { name, age } = getUserData();
console.log(name); // "Taro"
console.log(age);  // 28
JavaScript

6. ステップで追う(実行の流れを図解的に)

例:[maxValue, minValue] = maxAndMin(10, 7, 14) のとき

  1. maxAndMin が呼ばれる(a=10, b=7, c=14)。
  2. Math.max(10,7,14) → 14、Math.min(10,7,14) → 7。
  3. [14, 7] という配列を return
  4. 分割代入で maxValue = 14, minValue = 7 に代入される。

7. 練習問題

問題1:sumAndAverage という関数を作り、配列 [sum, average] を返してみよう。
ヒント:合計は足し算、平均は合計 ÷ 個数。

回答例(模範解答):

function sumAndAverage(numbers) {
  const sum = numbers.reduce((s, n) => s + n, 0);
  const avg = sum / numbers.length;
  return [sum, avg];
}

const [sum, avg] = sumAndAverage([10, 20, 30]);
console.log(sum); // 60
console.log(avg); // 20
JavaScript

問題2:同じ sumAndAverageオブジェクト{ sum: ..., average: ... } にして返すとどう書く?

模範解答:

function sumAndAverageObj(numbers) {
  const sum = numbers.reduce((s, n) => s + n, 0);
  const avg = sum / numbers.length;
  return { sum, average: avg };
}

const { sum, average } = sumAndAverageObj([10, 20, 30]);
console.log(sum);     // 60
console.log(average); // 20
JavaScript

8. もう少し踏み込んだテクニック(便利な小ネタ)

  • 既定値(デフォルト値):分割代入の時にデフォルト値を指定できます。
function demo() { return [1]; }
const [x = 0, y = 99] = demo(); // x=1, y=99(demoが2つ目を返さなければデフォルトが使われる)
JavaScript
  • 部分的に値だけ取りたいとき:配列の分割代入で途中を飛ばせます。
function triple() { return [10, 20, 30]; }
const [, second] = triple(); // second = 20(1つ目を飛ばして2番目だけ取る)
JavaScript
  • オブジェクトの名前を変えて受け取る
const { min: minimum, max: maximum } = maxAndMinObj(5, 2, 9);
JavaScript

9. どっちを使うべき?配列 vs オブジェクト

  • 配列
    • 要素の順序が明確で、要素が「同種(同じ意味合い)」のとき(例:座標 [x, y])に向く。
    • 短くて簡潔にしたいとき。
  • オブジェクト
    • 戻り値の各値に名前(意味)があるときに向く(例:{name, age, id})。
    • 順序に依存したくない、可読性を重視したい場面でおすすめ。

10. よくある質問(Q&A)

Q
「関数は本当に1つしか返せないの?」
A

JS の言語仕様上 return に与えるのは1つの式ですが、その式が配列やオブジェクトなら中に複数値を含められるので実質的には複数返せます

Q
「配列で返すと順番ミスが怖い」
A

その場合はオブジェクトにして「名前付き」で返すと安全です。

Q
「どっちが速い?」
A

実行速度の差は普通の場面では気にする必要はありません。可読性・保守性を優先してください。


11. 練習(チャレンジ)

  1. minMaxIndices(numbers) を作って、最小値と最大値のインデックス(位置)をオブジェクト { minIndex: ..., maxIndex: ... } で返してみよう。
  2. splitName(fullName) を作って、 "Taro Yamada" のような文字列を受け取り、{ first: "Taro", last: "Yamada" } を返す関数を書いてみよう。

12. 模範解答

では、前回の チャレンジ問題(応用)2問の「模範解答」と、
「ステップごとの動き」「初心者向けの解説」までつけて詳しく見ていきましょう。


問題①:minMaxIndices(numbers)

数値配列から「最小値」と「最大値」のインデックス(位置)を返す関数を作ろう。
戻り値はオブジェクト { minIndex: ..., maxIndex: ... } にする。


模範解答

function minMaxIndices(numbers) {
  const min = Math.min(...numbers);
  const max = Math.max(...numbers);

  const minIndex = numbers.indexOf(min);
  const maxIndex = numbers.indexOf(max);

  return { minIndex, maxIndex };
}

// 実行例
const result = minMaxIndices([5, 8, 3, 10, 7]);
console.log(result); // { minIndex: 2, maxIndex: 3 }
JavaScript

解説ステップ

  1. Math.min(...numbers)
    → 配列を展開(スプレッド構文)して最小値を求める。
    例:[5, 8, 3, 10, 7]Math.min(5, 8, 3, 10, 7)3
  2. indexOf(min)
    → 配列の中で「最初に3が出てくる位置」=インデックス2。
  3. 同様に Math.max(...numbers) → 10、indexOf(10) → 3。
  4. { minIndex, maxIndex }
    → オブジェクトで返すことで、意味のある名前でアクセスできる。

初心者向けポイント

  • ...numbers は「スプレッド構文」。配列を中身ごと展開する仕組み。
  • 戻り値を配列 [2, 3] にしてもいいけど、
    どっちが min でどっちが max か分かりにくいので、
    名前付き(オブジェクト)にするのがベターです。

問題②:splitName(fullName)

"Taro Yamada" のような文字列を " "(半角スペース)で分けて
{ first: "Taro", last: "Yamada" } にして返す関数を作ろう。


模範解答

function splitName(fullName) {
  const parts = fullName.split(" "); // " "で分割 → ["Taro", "Yamada"]

  const first = parts[0];
  const last = parts[1];

  return { first, last };
}

// 実行例
const user = splitName("Taro Yamada");
console.log(user.first); // "Taro"
console.log(user.last);  // "Yamada"
JavaScript

解説ステップ

  1. split(" ") で、文字列をスペース区切りに分割。
    "Taro Yamada"["Taro", "Yamada"]
  2. 配列の 0 番目が「名」、1 番目が「姓」。
  3. { first, last } を返すことで、呼び出し側が直感的に使える。

改良版(可変長対応)

実は "Hanako Suzuki Tanaka" のように
姓が2つあるケースだと、上のコードではズレます。
こういう場合は split の結果を工夫して「最後の要素を姓にする」と安全です👇

function splitName(fullName) {
  const parts = fullName.trim().split(" "); // trimで前後の空白も除去
  const first = parts[0];
  const last = parts.slice(1).join(" "); // 2番目以降をまとめて姓にする
  return { first, last };
}

console.log(splitName("Hanako Suzuki Tanaka"));
// { first: "Hanako", last: "Suzuki Tanaka" }
JavaScript

まとめ

方法特徴おすすめ度
配列 [a, b]シンプルだが順番依存⭐⭐
オブジェクト { a, b }名前付きで読みやすい⭐⭐⭐⭐
分割代入 { a, b } = func()コードがすっきり⭐⭐⭐⭐⭐
タイトルとURLをコピーしました