arguments#length の代替手段
Arrow functionで、あえて引数にundefinedを渡したことを識別する方法はあるのか
同じ疑問を持って調べた事がありますが、私が調べた範囲ではアロー関数に arguments#length
の代替手段はありませんでした。
残余引数(Rest parameters)
「...argsのように書いて、args.lengthをチェックする」
確かにこの方法でも実引数の数を参照できますが、Function#length
値を0にリセットする問題があり、厳密には arguments#length
の代替手段になりません。
JavaScript
1function fn1 (arg) { console.log(arguments.length); }
2const fn2 = (...args) => console.log(args.length);
3
4console.log(fn1.length); // 1
5console.log(fn2.length); // 0
残余引数(Rest parameters)は二通りの使い道があります。
- 可変引数を指定する
Function#length
値をコントロールする為にoptionalな引数に指定する
JavaScript
1function output (value, ...option) {
2 console.log(option[0] ? String(value) : value);
3}
4
5console.log(output.length); // 1
関数 output
の必須パラメータは第一引数であり、残余引数(Rest parameters)を使用することで output.length
値が 1
になるよう調整できます。
推奨or非推奨
なお、実用的にはそのような関数を書くべきではないでしょうし、れば動かすことは可能だということは間違いないです。
これには異論があります。
例えば、関数の多重定義(オーバーロード)を実装する場合、ECMAScriptには標準機能が存在しない為、arguments,length
を活用する必要があります。
JavaScript
1function overloadFunction () {
2 switch (arguments.length) {
3 case 0:
4 throw new Error('One or more arguments required');
5 case 1:
6 // 実引数が1個の処理
7 break;
8 case 2:
9 // 実引数が2個の処理
10 break;
11 case 3:
12 default:
13 // 実引数が3個以上の処理
14 break;
15 }
16}
また、Function#length
を利用した必須パラメータを判定する為にも arguments.length
は有効です。
JavaScript
1function sum (a, b) {
2 let i = arguments.length;
3
4 if (i < sum.length) {
5 throw new Error(sum.length + ' or more arguments required');
6 }
7
8 let result = 0;
9
10 while (i--) result += +arguments[i];
11
12 return result;
13}
14
15sum(1,2); // 3
16sum(1); // Error: 2 or more arguments required
ECMAScript 2020
ECMAScript 2020 には実引数の数に関連したErrorオブジェクトが存在しません。
実引数の数が不足した事に起因するエラーは大抵、TypeErrorになります。
JavaScript
1[].forEach(); // TypeError: undefined is not a function
ビルトイン関数の基本的な動きは
- 引数の型をチェック
- 引数の型が実行条件を満たさない場合は
TypeError
を返す
というもので、Undefined
型を要求する関数は(私の知る限りでは)存在しない為、引数の数が不足すれば型チェックによって TypeError
を返すケースが大半です。
ただし、それでも例外はあるもので、実引数の数を判定しているビルトイン関数も存在します。
JavaScript
1fetch(undefined); // エラーは発生しない
2fetch(); // TypeError: Failed to execute 'fetch' on 'Window': 1 argument required, but only 0 present.
結論
アロー関数に arguments.length
の代替手段はありません。
必要なら「関数宣言or関数式 + arguments.length
」を使用し、目的に応じて使い分ける必要があります。
Re: maisumakun さん