JavaScriptの関数の戻り値が複数ある場合の扱い方
生徒
「先生、JavaScriptの関数で戻り値が複数ある場合って、どうやって扱うんですか?」
先生
「JavaScriptの関数は、一度に一つの値しか戻せません。でも、戻したい値が複数ある場合は配列やオブジェクトにまとめて返す方法があります。」
生徒
「配列やオブジェクトって何ですか?難しそうです…」
先生
「大丈夫です。配列は複数の値を順番にまとめる箱、オブジェクトは名前付きで値をまとめる箱と思ってください。実際の使い方も見てみましょう!」
1. JavaScriptの関数は戻り値が1つだけ
JavaScriptの関数は、returnを使って戻り値を返します。しかし、1回のreturnで返せる値は1つだけです。
例えば、次の関数は数字を一つだけ返します。
function getNumber() {
return 10;
}
console.log(getNumber()); // 10
では、もし「合計」と「平均」など複数の値を返したい場合はどうするでしょうか?
2. 複数の値を返したいときは「配列」を使う方法
配列は複数の値を順番にまとめるデータの箱です。戻り値を配列にまとめて返すことで、複数の値を扱えます。
function calculateTotalAndAverage(scores) {
let total = 0;
for (let score of scores) {
total += score;
}
let average = total / scores.length;
return [total, average]; // 配列で返す
}
const result = calculateTotalAndAverage([80, 90, 100]);
console.log(result); // [270, 90]
console.log("合計:", result[0]);
console.log("平均:", result[1]);
このように配列の0番目や1番目の要素として取り出せますが、数字の順番を間違うとわかりにくくなることがあります。
3. 複数の値を返したいときは「オブジェクト」を使う方法
オブジェクトは「名前」と「値」をセットでまとめるデータの箱です。戻り値をオブジェクトにまとめて返すと、値に名前がつくのでわかりやすくなります。
function calculateTotalAndAverage(scores) {
let total = 0;
for (let score of scores) {
total += score;
}
let average = total / scores.length;
return { total: total, average: average }; // オブジェクトで返す
}
const result = calculateTotalAndAverage([80, 90, 100]);
console.log(result); // { total: 270, average: 90 }
console.log("合計:", result.total);
console.log("平均:", result.average);
このように名前で値を取り出せるので、コードが読みやすくミスも減らせます。
4. オブジェクトの省略記法と分割代入
JavaScriptでは、オブジェクトのキーと変数名が同じときに省略できます。
function calculateTotalAndAverage(scores) {
let total = 0;
for (let score of scores) {
total += score;
}
let average = total / scores.length;
return { total, average }; // 省略形
}
さらに、戻り値のオブジェクトから必要な値だけを取り出す「分割代入」も便利です。
const { total, average } = calculateTotalAndAverage([80, 90, 100]);
console.log("合計:", total);
console.log("平均:", average);
分割代入は、変数に直接値を割り当てられる方法です。
5. 配列で複数の戻り値を返す場合の分割代入
配列で戻り値を返したときも分割代入が使えます。ただし、順番に気をつける必要があります。
const [total, average] = calculateTotalAndAverage([80, 90, 100]);
console.log("合計:", total);
console.log("平均:", average);
配列の場合は順番で値が決まるので、順序を間違えないようにしましょう。
6. まとめ
JavaScriptの関数は戻り値が1つしか返せませんが、配列やオブジェクトにまとめることで複数の値を返すことができます。
配列は順番に値をまとめ、オブジェクトは名前付きで値をまとめるため、用途に合わせて使い分けると良いでしょう。
特にオブジェクトでの戻り値は、コードが読みやすく初心者にもおすすめです。
分割代入を使うと、戻り値から簡単に必要な値だけ取り出せて便利ですよ。
まとめ
ここまでJavaScriptにおける関数の戻り値について詳しく解説してきました。プログラミングを始めたばかりの頃は、「関数からは一つの値しか返せない」という制約に戸惑うこともあるかもしれません。しかし、今回ご紹介した「配列」や「オブジェクト」を活用するテクニックを習得すれば、複雑なデータ処理も驚くほどスムーズに行えるようになります。
配列とオブジェクト、どちらを選ぶべきか?
複数の戻り値を扱う際、配列(Array)を使うかオブジェクト(Object)を使うかは、そのデータの性質によって決めるのがベストです。
- 配列を使う場合: 値の順番に意味があるときや、座標(x, y)のようにセットで扱うことが直感的な場合に適しています。
- オブジェクトを使う場合: それぞれの値に「名前(キー)」を付けて、後から見返したときに何を表しているのか一目で分かるようにしたい場合に最適です。実務ではこちらの方がメンテナンス性が高く、推奨されるケースが多いです。
さらに高度なテクニック:TypeScriptでの型定義
最近の開発現場で主流となっているTypeScriptを使うと、戻り値の形式をより厳密に定義できます。これにより、エディタの補完機能が働き、記述ミスを未然に防ぐことが可能です。
interface CalculationResult {
sum: number;
diff: number;
}
function calculate(a: number, b: number): CalculationResult {
return {
sum: a + b,
diff: a - b
};
}
const { sum, diff } = calculate(20, 10);
console.log(`合計: ${sum}, 差: ${diff}`);
このように、インターフェース(interface)を定義することで、どの関数がどのような値を返すのかが明確になり、多人数での開発でも混乱が起きにくくなります。
実践的な応用例:APIレスポンスのシミュレーション
実際のWebアプリ開発では、サーバーからデータを取得する際にも複数の情報がセットで返ってきます。例えば、ユーザーの基本情報とステータスを同時に取得するような関数を想定してみましょう。
function fetchUserProfile(userId) {
// 本来はここでデータベースやAPIから取得しますが、今回は固定値を返します
const userData = {
id: userId,
name: "田中太郎",
email: "tanaka@example.com",
isAdmin: true
};
const loginStatus = "online";
// オブジェクトにまとめて返す
return { userData, loginStatus };
}
// 分割代入で受け取る
const { userData, loginStatus } = fetchUserProfile(123);
console.log(`${userData.name}さんは現在${loginStatus}です。`);
実行結果は以下のようになります。
田中太郎さんは現在onlineです。
分割代入の利便性を再確認
コードをスッキリさせる「分割代入」は、ES6以降のJavaScriptにおいて欠かせない文法です。これを使わない場合と使う場合で、どれほど見た目が変わるか比較してみましょう。
【分割代入を使わない場合】
const resultObj = fetchUserProfile(456);
const name = resultObj.userData.name;
const status = resultObj.loginStatus;
【分割代入を使う場合】
const { userData: { name }, loginStatus: status } = fetchUserProfile(456);
少し複雑に見えるかもしれませんが、入れ子構造になったオブジェクトからも一気に値を取り出すことができます。これにより、コードの行数を減らし、ロジックの本質部分に集中できるようになります。
エラーハンドリングを含めた戻り値の設計
複数の値を返す際、成功したかどうかのフラグを一緒に返す手法もよく使われます。これにより、呼び出し側で条件分岐がしやすくなります。
function safeDivide(a, b) {
if (b === 0) {
return { success: false, message: "0で割ることはできません", value: null };
}
return { success: true, message: "計算成功", value: a / b };
}
const response = safeDivide(10, 0);
if (!response.success) {
console.error(response.message);
} else {
console.log("結果:", response.value);
}
実行結果:
0で割ることはできません
単に数値だけを返すのではなく、付加情報をオブジェクトに含めることで、堅牢なプログラムを作成することが可能になります。
生徒
「先生、ありがとうございました!最初は『戻り値は1つだけ』っていう言葉に縛られて悩んでいましたが、結局は『1つのパッケージにして返せばいい』ということだったんですね。目から鱗でした!」
先生
「その通りです!素晴らしい気づきですね。箱の種類として『配列』を使うか『オブジェクト』を使うか、その選択が重要になってきます。実際に書いてみて、どちらが使いやすかったですか?」
生徒
「僕はオブジェクトの方が好きかもしれません。result[0]って書くよりも、result.totalって書いてある方が、後でコードを読み返したときに『ああ、ここでは合計値を扱ってるんだな』ってすぐに思い出せそうですし。」
先生
「まさにそれがオブジェクトを使う最大のメリットです。プログラミングは書く時間よりも読む時間の方が長いと言われていますから、自分やチームのメンバーが読みやすいコードを意識するのはとても良い姿勢ですよ。」
生徒
「あと、分割代入も練習してみます!最初は書き方に慣れなくてドキドキしましたが、使いこなせれば変数定義がすごく楽になりそうです。関数の戻り値を受け取るのが楽しくなりそうですね。」
先生
「いいですね、その調子です。分割代入はReactなどのモダンなライブラリでも頻繁に登場するので、今のうちにマスターしておくと将来的に役立ちますよ。次は、この戻り値を活用して、もっと複雑なロジックを組み立てる練習をしていきましょうか!」
生徒
「はい!ぜひお願いします。もっと色々なコードを書いて、自在にデータを操れるようになりたいです!」