はじめに
実装していた際、引数を下記どちらの形式で受け取るか迷うことがありました。
-
(a, b)のように 順番で渡す位置引数 -
{ a, b }のように 名前で渡すオブジェクト引数
そのため、違いや特徴をまとめてみます。
順番で渡す位置引数
前提
JavaScript/TypeScriptは、引数を「位置(順番)」で受け取る仕組みがある。
function sample(a, b) {}
sample(1, 2); // a=1, b=2
問題点
呼び出し側が順番を覚えてないと壊れてしまう
sample(a, b);
→ 順番間違えるだけで致命傷になる
コンパイル時にTypeScriptで検出できないケースもあるので、要注意。
(型が同じ場合など)
結果、引数が増えるとメンテナンス性が悪くなる。
名前で渡すオブジェクト引数
書き方
定義
function sample({ a, b, c }) {}
呼び出し①
const a = 1;
const b = 2;
const c = 3;
sample({ a, b, c });
呼び出し②
sample({
a: 1,
b: 2,
c: 3,
});
呼び出し③
const x = 10;
const y = 20;
const z = 30;
sample({
a: x,
b: y,
c: z,
});
順番で渡す位置引数との違い
①順番を覚える必要がない
sample({ a, b });
sample({ b, a });
→ 順番を入れ替えても問題がない!
②引数の追加・変更に強い
オブジェクト引数は、必要なものだけ渡せば動くため、後からプロパティを追加しても既存コードが壊れない。
定義
function sample({
a,
b,
c,
d = false, // ← 新しいオプション(デフォルト値付き)
}: {
a: number;
b: number;
c: number;
d?: boolean;
}) {}
呼び出し
sample({ a: 1, b: 2, c: 3 });
ポイント
- dが追加されたがオプションなので呼び出し側は無視できる
- 未設定の場合は
d = falseが自動適用されるため、TypeScriptも怒らないし、動作も壊れない
※一引数でもoptionalやデフォルト値は使える。ただし、一番後ろの引数にしか使えないという強い制約がある。
オブジェクト引数は、「名前で渡す」から順番の影響がない!
③読んだ瞬間に意味がわかる
引数に名前がついているので、何を渡しているかが一目でわかる。
まとめ
位置引数は順番に依存するため、引数が増えるほど壊れやすく、optionalの扱いにも制約があります。
一方、オブジェクト引数は名前で渡せるため意味が明確で読みやすく、どの引数も自由にoptionalにでき、将来的な引数追加にも強い柔軟な設計が可能ということがわかりました!