JavaScript | 基礎構文:関数 – デフォルト引数

JavaScript JavaScript
スポンサーリンク

デフォルト引数って何者?

デフォルト引数は、
「引数が渡されなかったときに使う“あらかじめ決めておく値”」 です。

「この引数は省略されることもあるけど、そのときはこの値を使ってね」
という“保険”を関数側で用意しておくイメージです。

JavaScript は引数が足りなくてもエラーにならず undefined になるので、
そのままだとバグの原因になりやすい。
そこで「undefined のときはこの値にする」と最初から書いておけるのが、デフォルト引数です。


一番シンプルなデフォルト引数の例

引数が省略されたときの挨拶

まずは基本形から。

function greet(name = "ゲスト") {
  console.log("こんにちは、" + name + "さん");
}

greet("太郎"); // こんにちは、太郎さん
greet();       // こんにちは、ゲストさん
JavaScript

name = "ゲスト" がデフォルト引数です。

greet("太郎") と呼ぶときは、name"太郎" が入ります。
greet() と呼ぶときは、引数が渡されていないので name には "ゲスト" が入ります。

ここが重要です。
「引数が undefined のとき、その右側に書いた値が使われる」
これがデフォルト引数のルールです。


デフォルト引数がないとどうなるか

何も指定しないと undefined になる

デフォルト引数を使わない場合を見てみます。

function greet(name) {
  console.log("こんにちは、" + name + "さん");
}

greet(); // こんにちは、undefinedさん
JavaScript

name には何も渡されていないので undefined
そのまま文字列連結すると「undefinedさん」となってしまいます。

これを避けるために、昔は関数の中でこう書いていました。

function greet(name) {
  if (name === undefined) {
    name = "ゲスト";
  }
  console.log("こんにちは、" + name + "さん");
}
JavaScript

デフォルト引数を使えば、
この「最初の if チェック」を関数定義のところにまとめて書ける、というわけです。


複数のデフォルト引数

送料込みの価格計算の例

複数の引数にデフォルト値をつけることもできます。

function calcPrice(price, shipping = 500, taxRate = 0.1) {
  const total = (price + shipping) * (1 + taxRate);
  return total;
}

console.log(calcPrice(1000));              // 送料500・税率10%
console.log(calcPrice(1000, 0));           // 送料無料・税率10%
console.log(calcPrice(1000, 500, 0.08));   // 送料500・税率8%
JavaScript

ここでは、

price は必須
shipping は省略されたら 500
taxRate は省略されたら 0.1

というルールになっています。

ここが重要です。
「どの引数を“必須”にして、どの引数を“省略可+デフォルト値あり”にするか」
は関数設計の大事なポイントです。


デフォルト引数が使われる条件

「undefined のときだけ」デフォルトが効く

デフォルト引数は「引数が undefined のとき」にだけ使われます。

function show(value = "デフォルト") {
  console.log(value);
}

show("指定あり");   // 指定あり
show();             // デフォルト
show(undefined);    // デフォルト
show(null);         // null
JavaScript

show(null) のときは、valuenull なのでデフォルトは使われません。
undefined かどうか」がポイントです。

ここを勘違いしやすいので、
null は“値がある(空という意味の値)”、undefined は“そもそも渡されていない”」
と意識しておくと混乱しにくくなります。


デフォルト引数に式や関数を使う

計算結果をデフォルトにする

デフォルト値には、単なるリテラルだけでなく式も書けます。

function createUser(name = "ゲスト", createdAt = new Date()) {
  return { name, createdAt };
}

const user1 = createUser();
const user2 = createUser("太郎");

console.log(user1);
console.log(user2);
JavaScript

createdAt = new Date() としておくと、
引数が省略されたときに「その呼び出し時点の日時」が入ります。

他の引数を使ったデフォルト

デフォルト引数は、前の引数を使うこともできます。

function repeat(text, times = text.length) {
  return text.repeat(times);
}

console.log(repeat("A"));     // "A" を1文字なので1回 → "A"
console.log(repeat("AB"));    // "AB" を2文字なので2回 → "ABAB"
console.log(repeat("X", 5));  // "X" を5回 → "XXXXX"
JavaScript

ここが重要です。
デフォルト引数は「ただの固定値」ではなく、
「呼び出し時に評価される式」としても使える。
これで“賢い初期値”を作れる。


オブジェクト引数+デフォルト値の組み合わせ

実務でよくある「オプション引数」のパターン

実務では、
「設定オプションをオブジェクトで受け取り、足りないところはデフォルトを補う」
というパターンがよく出てきます。

function setup(options = {}) {
  const {
    color = "blue",
    size = "medium",
    enabled = true,
  } = options;

  console.log(color, size, enabled);
}

setup(); // blue medium true
setup({ color: "red" }); // red medium true
setup({ size: "small", enabled: false }); // blue small false
JavaScript

ここでは、

関数の引数 options 自体にデフォルト {} を設定
その中身を分割代入しつつ、各プロパティにもデフォルト値を設定

という二段構えになっています。

ここが重要です。
「オブジェクト引数+デフォルト引数+分割代入」は、
“オプションを柔軟に受け取りつつ、足りないところは補う”ための鉄板パターン。


デフォルト引数を使うときに意識してほしいこと

「この引数は省略されたらどう解釈されるべきか?」

デフォルト引数は、
「省略されたときの意味」を関数側で決めるための仕組み です。

例えば、

ページ番号が省略されたら 1 ページ目とみなす
言語が省略されたらブラウザの言語を使う
オプションが省略されたら「よくある標準設定」を使う

など、「自然な初期値」を決めておくと、
呼び出し側のコードがスッキリします。

逆に、
「この引数は絶対に必要。省略されたらおかしい」
というものには、あえてデフォルトをつけない方がいいこともあります。

ここが重要です。
デフォルト引数は「なんでもかんでもつけるもの」ではなく、
“省略されることが自然な引数”にだけつけると、設計として美しくなります。


初心者として「デフォルト引数」で本当に押さえてほしいこと

デフォルト引数は、

function func(arg = 初期値) { ... }
JavaScript

という形で書き、
「引数が undefined のときにだけ、その初期値が使われる」 もの。

メリットは、

関数の中で「if (arg === undefined)」と書かなくてよくなる
「省略されたときの意味」が関数定義の場所で一目で分かる
呼び出し側がシンプルになる

特に実務では、

オプション引数
設定オブジェクト
ページングやフィルタのパラメータ

などで頻繁に使います。

もし今書いている関数で、
「引数が省略されたときに中で if (arg === undefined) としている場所」があったら、
そこはデフォルト引数に書き換えられるポイントです。
一箇所書き換えてみると、「あ、こういうときに使うのか」が一気に腑に落ちます。

タイトルとURLをコピーしました