関数の引数 (function parameter)
引数の個数
JavaScriptの関数では、関数が期待する引数の個数と、関数を呼び出した際に渡した引数の数が一致していなくても、関数が呼び出せます。つまり、JavaScriptは引数のチェックを行わないということです。たとえば、引数が1つ渡されることを期待する関数を、引数2つで呼び出してもエラーになりません。
js
functionincrement (n ) {returnn + 1;}increment (1, 2); // OK
js
functionincrement (n ) {returnn + 1;}increment (1, 2); // OK
逆に、JavaScriptでは、引数が少ない場合であっても関数が実行されます。その際、渡されなかった引数の値はundefined
になります。
js
functionfoo (a ,b ) {console .log (b );}foo (1); // 引数が足りない
js
functionfoo (a ,b ) {console .log (b );}foo (1); // 引数が足りない
基本的に引数が多く渡される分には、関数の実行が問題になることはありません。余分な引数は無視してしまえばよいからです。それでも、引数の個数を厳密にチェックしたいケースでは、変数arguments
のlength
プロパティで引数の数をチェックします。
js
functionfoo (a ,b ) {if (arguments .length > 2) {throw newError ("引数の数は2つまでです");}}foo (1, 2); // OKfoo (1, 2, 3); // エラー
js
functionfoo (a ,b ) {if (arguments .length > 2) {throw newError ("引数の数は2つまでです");}}foo (1, 2); // OKfoo (1, 2, 3); // エラー
JavaScriptでは、上のように引数の数をチェックするには、そのためのロジックを書く必要があります。
TypeScriptでは、関数の引数の数が一致していないとコンパイルエラーになります。
ts
functionincrement (n ) {returnn + 1;}Expected 1 arguments, but got 2.2554Expected 1 arguments, but got 2.increment (1,2 ); // 引数が多いExpected 1 arguments, but got 0.2554Expected 1 arguments, but got 0.increment (); // 引数が足りない
ts
functionincrement (n ) {returnn + 1;}Expected 1 arguments, but got 2.2554Expected 1 arguments, but got 2.increment (1,2 ); // 引数が多いExpected 1 arguments, but got 0.2554Expected 1 arguments, but got 0.(); // 引数が足りない increment
そのため、TypeScriptではJavaScriptのようにチェックロジックを書く必要はありません。
引数の型
JavaScriptは、引数の型についてもチェックを行いません。JavaやPHPなどの他のプログラミング言語の中には、関数の引数の型を定義することで、関数が期待する引数の型と異なる値が渡されたときに、関数実行前にエラーにしてくれる言語があります。JavaScriptにはこのような機能がありません。たとえば、string型の引数を期待する関数に、null型の値を渡しても、JavaScriptの関数は実行されます。
js
functionlen (str ) {returnstr .length ;}console .log (len (null));
js
functionlen (str ) {returnstr .length ;}console .log (len (null));
この関数len
の引数str
はstring型であることを想定していますが、渡される値はnull
です。それでも、関数の実行自体は行われ、null
に存在しないlength
プロパティへの参照を試みる段階でやっとエラーになります。
JavaScriptでは、引数の型を厳密にする場合、チェック処理を書く必要があります。たとえば、引数がnumber型やstring型などのプリミティブ型かのチェックはこのtypeof
演算子を使って行います。
js
functionlen (str ) {if (typeofstr !== "string") {throw newError ("strは文字列型にしてください");}returnstr .length ;}len ("a"); // OKlen (1); // エラー
js
functionlen (str ) {if (typeofstr !== "string") {throw newError ("strは文字列型にしてください");}returnstr .length ;}len ("a"); // OKlen (1); // エラー
TypeScriptでは、関数の引数に型注釈が書けます。型注釈を書いておくと、引数に意図しない型を書くとコンパイルエラーになります。
ts
functionlen (str : string) {returnstr .length ;}len ("a"); // OKArgument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.len (1 ); // エラー
ts
functionlen (str : string) {returnstr .length ;}len ("a"); // OKArgument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.len (1 ); // エラー
そのため、TypeScriptではJavaScriptのように型チェックの処理を書く必要はありません。