JavaScript returnとは?関数の戻り値を初心者向けに解説
JavaScriptのreturn文の基本的な使い方から応用テクニックまで詳しく解説。関数の戻り値、早期リターン、複数の戻り値の返し方を初心者向けに分かりやすく説明します。
JavaScript returnとは?関数の戻り値を初心者向けに解説
「JavaScriptで関数を書いているけど、return文って何?」と疑問に思ったことはありませんか?
「関数から値を返すってどういうこと?」 「returnを書かないとどうなるの?」 「どんな値を返せばいいの?」
そんな疑問を抱いている方は多いと思います。 でも大丈夫です!
この記事では、JavaScriptのreturn文について基本から応用まで詳しく解説します。 関数の戻り値、早期リターン、複数の戻り値の返し方を、実際のコード例とともに初心者向けに分かりやすく説明していきます。
きっと「returnってこんなに便利だったんだ!」と感じられるはずですよ。
return文ってどんなもの?
基本的な仕組みを理解しよう
return文は、関数の実行を終了して、呼び出し元に値を返すためのJavaScriptの制御構文です。
簡単に言うと、関数が処理した結果を外部に渡すための仕組みです。 イメージとしては、お店で商品を注文して、店員さんが商品を渡してくれるような感じですね。
基本的な書き方を見てみよう
function functionName() { // 処理 return 値; // 関数の実行を終了し、値を返す}
// 使用例function greet() { return "こんにちは!";}
let message = greet();console.log(message); // "こんにちは!"
この例では、greet
関数が「こんにちは!」という文字列を返しています。
return
の後に書いた値が、関数を呼び出した場所に渡されます。
return文の重要な働き
function add(a, b) { console.log("計算を開始します"); let result = a + b; console.log("計算が完了しました"); return result; // ここで関数の実行が終了 console.log("この行は実行されません"); // 到達不可能なコード}
let sum = add(3, 5);console.log(sum); // 8
return文が実行されると、その時点で関数の実行が終了します。 それ以降のコードは実行されないので注意しましょう。
これにより、条件に応じて処理を途中で終了させることもできます。
戻り値の基本パターンを覚えよう
数値や文字列を返す関数
様々な種類の値を返す関数を見てみましょう。
// 数値を返すfunction multiply(x, y) { return x * y;}
// 文字列を返すfunction createFullName(firstName, lastName) { return firstName + " " + lastName;}
// 真偽値を返すfunction isEven(number) { return number % 2 === 0;}
使用例を見てみましょう。
console.log(multiply(4, 5)); // 20console.log(createFullName("太郎", "山田")); // "太郎 山田"console.log(isEven(10)); // trueconsole.log(isEven(7)); // false
multiply
は二つの数値の掛け算結果を返します。
createFullName
は名前と姓を組み合わせた文字列を返します。
isEven
は数値が偶数かどうかの真偽値を返します。
オブジェクトを返す関数
複数の情報をまとめてオブジェクトで返すこともできます。
function createUser(name, age, email) { return { name: name, age: age, email: email, createdAt: new Date() };}
// ES6の省略記法function createUserShort(name, age, email) { return { name, age, email, createdAt: new Date() };}
実際に使ってみましょう。
let user = createUser("佐藤花子", 25, "hanako@example.com");console.log(user);/*{ name: "佐藤花子", age: 25, email: "hanako@example.com", createdAt: 2025-07-06T...}*/
オブジェクトを返すことで、複数の関連する情報を一度に扱えます。 ユーザー情報や設定データなど、実用的な場面でよく使われるパターンです。
配列を返す関数
配列を返す関数も便利です。
function getTopScores(scores, count) { return scores.sort((a, b) => b - a).slice(0, count);}
function splitName(fullName) { return fullName.split(" ");}
function range(start, end) { let result = []; for (let i = start; i <= end; i++) { result.push(i); } return result;}
使用例を見てみましょう。
let scores = [85, 92, 78, 95, 88];console.log(getTopScores(scores, 3)); // [95, 92, 88]
console.log(splitName("田中 太郎")); // ["田中", "太郎"]
console.log(range(1, 5)); // [1, 2, 3, 4, 5]
getTopScores
は上位のスコアを配列で返します。
splitName
は名前を分割して配列で返します。
range
は指定した範囲の数値配列を作成して返します。
return文を使わない場合はどうなる?
undefinedが返される
return文を書かない関数は、自動的にundefined
を返します。
function sayHello() { console.log("Hello!"); // return文なし}
function doSomething() { let x = 5; let y = 10; // 計算はするが値を返さない}
let result1 = sayHello(); // "Hello!"が出力されるlet result2 = doSomething();
console.log(result1); // undefinedconsole.log(result2); // undefined
処理は実行されますが、戻り値はundefined
になります。
これは想定外の動作を引き起こす可能性があるので注意しましょう。
明示的にundefinedを返す
条件によってはあえてundefined
を返すこともあります。
function processData(data) { if (!data) { return; // undefinedを返す(明示的) } // データを処理 return "処理完了";}
console.log(processData(null)); // undefinedconsole.log(processData("data")); // "処理完了"
return;
と書くことで、明示的にundefined
を返せます。
データが無効な場合などに使われるパターンです。
条件分岐とreturn文の使い方
早期リターンで読みやすいコードに
条件分岐でreturn文を使うと、コードがとても読みやすくなります。
従来の深いネストの例を見てみましょう。
// 従来の方法(深いネスト)function validateUser(user) { if (user) { if (user.name) { if (user.age >= 0) { if (user.email) { return "有効なユーザーです"; } else { return "メールアドレスが必要です"; } } else { return "年齢が無効です"; } } else { return "名前が必要です"; } } else { return "ユーザーデータが必要です"; }}
早期リターンを使った改善版を見てみましょう。
// 早期リターンを使った方法(フラット)function validateUserImproved(user) { if (!user) { return "ユーザーデータが必要です"; } if (!user.name) { return "名前が必要です"; } if (user.age < 0) { return "年齢が無効です"; } if (!user.email) { return "メールアドレスが必要です"; } return "有効なユーザーです";}
早期リターンを使うことで、コードがフラットで読みやすくなります。 エラーチェックを先に行い、問題があれば即座に終了するパターンです。
複数の戻り値パターン
成績評価のような場面でも活用できます。
function calculateGrade(score) { if (score >= 90) { return "A"; } else if (score >= 80) { return "B"; } else if (score >= 70) { return "C"; } else if (score >= 60) { return "D"; } else { return "F"; }}
// より簡潔な書き方function calculateGradeSimple(score) { if (score >= 90) return "A"; if (score >= 80) return "B"; if (score >= 70) return "C"; if (score >= 60) return "D"; return "F";}
使用例を見てみましょう。
console.log(calculateGrade(95)); // "A"console.log(calculateGrade(75)); // "C"console.log(calculateGrade(45)); // "F"
このように、条件に応じて異なる値を返すことができます。
実践的な使用例を見てみよう
計算関数の実装
実用的な計算関数を作ってみましょう。
// 基本的な計算関数function calculate(operation, a, b) { switch (operation) { case "add": return a + b; case "subtract": return a - b; case "multiply": return a * b; case "divide": if (b === 0) { return "0で割ることはできません"; } return a / b; default: return "未対応の演算です"; }}
使用例を見てみましょう。
console.log(calculate("add", 10, 5)); // 15console.log(calculate("divide", 10, 0)); // "0で割ることはできません"console.log(calculate("power", 2, 3)); // "未対応の演算です"
switch
文と組み合わせることで、操作に応じた結果を返せます。
より複雑な税金計算も作れます。
function calculateTax(price, taxRate = 0.1) { if (price < 0) { return { error: "価格は0以上である必要があります" }; } let tax = price * taxRate; let total = price + tax; return { price: price, tax: Math.round(tax), total: Math.round(total) };}
console.log(calculateTax(1000));/*{ price: 1000, tax: 100, total: 1100}*/
オブジェクトを返すことで、複数の計算結果を一度に提供できます。
配列処理関数の実装
配列を扱う実用的な関数も作れます。
// 配列から特定の条件の要素を取得function findUserById(users, id) { for (let user of users) { if (user.id === id) { return user; } } return null; // 見つからない場合}
// 配列の統計情報を返すfunction getArrayStats(numbers) { if (!numbers || numbers.length === 0) { return { error: "空の配列です" }; } let sum = numbers.reduce((acc, num) => acc + num, 0); let average = sum / numbers.length; let max = Math.max(...numbers); let min = Math.min(...numbers); return { count: numbers.length, sum: sum, average: average, max: max, min: min };}
実際に使ってみましょう。
let users = [ { id: 1, name: "太郎" }, { id: 2, name: "花子" }, { id: 3, name: "次郎" }];
console.log(findUserById(users, 2)); // { id: 2, name: "花子" }console.log(findUserById(users, 5)); // null
let scores = [85, 92, 78, 95, 88];console.log(getArrayStats(scores));/*{ count: 5, sum: 438, average: 87.6, max: 95, min: 78}*/
配列処理では、見つからない場合や無効な入力への対応も重要です。
文字列処理関数の実装
文字列を扱う便利な関数も作れます。
// 文字列の処理結果を返すfunction formatName(name) { if (!name || typeof name !== "string") { return "無効な名前です"; } // 前後の空白を除去し、各単語の最初を大文字に return name.trim() .split(" ") .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) .join(" ");}
// URLの妥当性チェックfunction validateURL(url) { if (!url) { return { valid: false, error: "URLが入力されていません" }; } try { let urlObj = new URL(url); return { valid: true, protocol: urlObj.protocol, hostname: urlObj.hostname, pathname: urlObj.pathname }; } catch (error) { return { valid: false, error: "無効なURLです" }; }}
使用例を見てみましょう。
console.log(formatName(" taro yamada ")); // "Taro Yamada"console.log(formatName("")); // "無効な名前です"
console.log(validateURL("https://example.com/path"));/*{ valid: true, protocol: "https:", hostname: "example.com", pathname: "/path"}*/
console.log(validateURL("invalid-url"));/*{ valid: false, error: "無効なURLです"}*/
文字列処理では、入力値の検証とエラーハンドリングが重要ですね。
複数の値を返すテクニック
配列で複数の値を返す
一つの関数から複数の値を返したい場合があります。
function getNameParts(fullName) { let parts = fullName.split(" "); return [parts[0], parts[1]]; // 配列で返す}
// 分割代入で受け取るlet [firstName, lastName] = getNameParts("山田 太郎");console.log(firstName); // "山田"console.log(lastName); // "太郎"
数学的計算での例も見てみましょう。
function divideWithRemainder(dividend, divisor) { let quotient = Math.floor(dividend / divisor); let remainder = dividend % divisor; return [quotient, remainder];}
let [quotient, remainder] = divideWithRemainder(17, 5);console.log(`商: ${quotient}, 余り: ${remainder}`); // "商: 3, 余り: 2"
配列で返すことで、関連する複数の値を一度に取得できます。
オブジェクトで複数の値を返す
オブジェクトを使う方法もあります。
function analyzePassword(password) { let length = password.length; let hasUppercase = /[A-Z]/.test(password); let hasLowercase = /[a-z]/.test(password); let hasNumbers = /\d/.test(password); let hasSpecialChars = /[!@#$%^&*(),.?":{}|<>]/.test(password); let score = 0; if (length >= 8) score++; if (hasUppercase) score++; if (hasLowercase) score++; if (hasNumbers) score++; if (hasSpecialChars) score++; return { length: length, hasUppercase: hasUppercase, hasLowercase: hasLowercase, hasNumbers: hasNumbers, hasSpecialChars: hasSpecialChars, score: score, strength: score <= 2 ? "弱い" : score <= 4 ? "普通" : "強い" };}
実際に使ってみましょう。
let analysis = analyzePassword("MyPassword123!");console.log(analysis);/*{ length: 13, hasUppercase: true, hasLowercase: true, hasNumbers: true, hasSpecialChars: true, score: 5, strength: "強い"}*/
オブジェクトで返すことで、各項目に名前が付いて分かりやすくなります。
関数を返す関数(高階関数)
関数自体を返すこともできます。
// 関数を返す関数function createMultiplier(factor) { return function(number) { return number * factor; };}
// 使用例let double = createMultiplier(2);let triple = createMultiplier(3);
console.log(double(5)); // 10console.log(triple(4)); // 12
もう少し実用的な例も見てみましょう。
function createValidator(rules) { return function(data) { let errors = []; for (let field in rules) { let rule = rules[field]; let value = data[field]; if (rule.required && !value) { errors.push(`${field}は必須です`); } if (rule.minLength && value && value.length < rule.minLength) { errors.push(`${field}は${rule.minLength}文字以上である必要があります`); } } return { valid: errors.length === 0, errors: errors }; };}
let userValidator = createValidator({ name: { required: true, minLength: 2 }, email: { required: true, minLength: 5 }});
console.log(userValidator({ name: "太郎", email: "taro@example.com" }));// { valid: true, errors: [] }
console.log(userValidator({ name: "", email: "a" }));// { valid: false, errors: ["nameは必須です", "emailは5文字以上である必要があります"] }
関数を返すことで、設定可能で再利用しやすい処理を作れます。
アロー関数とreturn文
暗黙的なreturnを活用
アロー関数では、return文を省略できる場合があります。
// 通常の関数function add(a, b) { return a + b;}
// アロー関数(明示的なreturn)let addArrow = (a, b) => { return a + b;};
// アロー関数(暗黙的なreturn)let addArrowShort = (a, b) => a + b;
// オブジェクトを返す場合は括弧で囲むlet createUser = (name, age) => ({ name, age });
使用例を見てみましょう。
console.log(add(3, 5)); // 8console.log(addArrow(3, 5)); // 8console.log(addArrowShort(3, 5)); // 8console.log(createUser("太郎", 25)); // { name: "太郎", age: 25 }
一行で書ける処理では、暗黙的なreturnが便利です。 オブジェクトを返す場合は括弧で囲むことを忘れずに。
配列メソッドでの活用
アロー関数は配列メソッドでよく使われます。
let numbers = [1, 2, 3, 4, 5];
// map:各要素を変換let doubled = numbers.map(n => n * 2);console.log(doubled); // [2, 4, 6, 8, 10]
// filter:条件に合う要素を抽出let evenNumbers = numbers.filter(n => n % 2 === 0);console.log(evenNumbers); // [2, 4]
// find:条件に合う最初の要素を返すlet firstBigNumber = numbers.find(n => n > 3);console.log(firstBigNumber); // 4
// some:条件に合う要素が存在するかチェックlet hasEven = numbers.some(n => n % 2 === 0);console.log(hasEven); // true
// every:すべての要素が条件を満たすかチェックlet allPositive = numbers.every(n => n > 0);console.log(allPositive); // true
配列メソッドでは、アロー関数の暗黙的なreturnがとても便利ですね。
よくある間違いとその対策
returnを忘れる間違い
計算結果を返すのを忘れがちです。
// 間違い:計算結果を返さないfunction calculateTotal(items) { let total = 0; for (let item of items) { total += item.price; } // returnを忘れている}
// 正しい:計算結果を返すfunction calculateTotalCorrect(items) { let total = 0; for (let item of items) { total += item.price; } return total;}
処理を書いただけでは、結果を外部に渡せません。 return文を書くことで、処理結果を活用できるようになります。
条件分岐でreturnを忘れる
すべての条件でreturnしていない場合があります。
// 間違い:すべての条件でreturnしていないfunction getDiscount(amount) { if (amount >= 10000) { return 0.1; // 10%割引 } else if (amount >= 5000) { return 0.05; // 5%割引 } // else の場合のreturnがない}
// 正しい:すべての条件でreturnするfunction getDiscountCorrect(amount) { if (amount >= 10000) { return 0.1; } else if (amount >= 5000) { return 0.05; } return 0; // 割引なし}
すべての条件でreturnすることで、予期しないundefined
を防げます。
非同期処理でのreturn
非同期処理では注意が必要です。
// 間違い:非同期処理の結果を直接返そうとするfunction fetchData() { let result; fetch("/api/data") .then(response => response.json()) .then(data => { result = data; }); return result; // undefinedが返される}
// 正しい:Promiseを返すfunction fetchDataCorrect() { return fetch("/api/data") .then(response => response.json());}
// または async/await を使用async function fetchDataAsync() { let response = await fetch("/api/data"); return await response.json();}
非同期処理では、Promiseを返すかasync/await
を使いましょう。
まとめ
JavaScriptのreturn文について詳しく解説しました。
基本的な働きをおさらい
- 関数の実行を終了する
- 呼び出し元に値を返す
- return文以降のコードは実行されない
これらの基本的な働きを理解することが重要です。
戻り値の種類を覚えよう
様々な種類の値を返すことができます。
- 基本的な値(数値、文字列、真偽値)
- オブジェクトや配列
- 関数(高階関数)
- undefinedまたはnull
用途に応じて適切な形式を選択しましょう。
実践での活用ポイント
- 早期リターンでコードを簡潔に
- 複数の値を配列やオブジェクトで返す
- 条件分岐での適切な戻り値
- 非同期処理でのPromiseの返却
これらのテクニックを覚えることで、より実用的な関数を作れます。
注意すべきポイント
- すべての条件でreturnを忘れない
- 非同期処理では適切にPromiseを返す
- アロー関数での暗黙的return
- デバッグ時の情報出力
return文を適切に使用することで、再利用可能で保守しやすい関数を作成できます。
まずは基本的な使い方から始めて、徐々に複雑な戻り値パターンにも挑戦してみてください。 ぜひ今日から、これらの知識を活用してより効果的なJavaScript関数を書いてみませんか?