【JavaScript】 関数の引数について今更知ったこと
更新日:2020/02/29
関数に値を渡すときは引数を使う。
当たり前すぎて僕は何も気にせず、調べもせず使っていました。
しかしJavaScriptの引数は少し奥が深いようです。
そこで今回は、JavaScriptの引数について少し詳しく調べてみました。
引数の基本
とりあえず普通の引数について。
JavaScript
function a( b ){ // 関数宣言
alert(b);
}
a( "test!" ); // 関数呼び出し
上のコードをブラウザで実行すると、下のような画面で「test!」と表示されます。
この時、関数aの引数としてbを定義しています。
function a( | b | ){ alert( | b | ); } | // 関数宣言 |
↑ | ↑ | ||||
仮引数(パラメータ) | 関数の中で使用できる |
引数のbは、そのまま関数内部のコードで使用できます。
関数を実行する際に、次のように値を渡します。
a( | "test!" | ); | // 関数呼び出し | |
↑ | ||||
実引数(引数) |
厳密には引数とは呼び出し時に渡す値を指します。
宣言内の定義はパラメータです。
ですが一般的にはどちらも引数として認識されています。
ここでは、全て引数と記述していきます。
自分でも区別しきれないからですね
その通りです。
複数指定とデフォルト値
引数を複数指定したり、引数を渡すときに足りなかったりするケースを考えてみます。
引数は複数指定できる
引数は一つだけでなくて、複数個指定できます。
JavaScript
function a( b, c, d ){ // 関数宣言
alert(b+" "+c+" "+d);
}
a( "test!", "test!!", "test!!!" ); // 関数呼び出し
呼び出し側で引数の数が足りない場合
呼び出し側で引数の数が足りない場合、undefinedがセットされます。
JavaScript
function a( b, c, d ){ // 関数宣言
alert(b+" "+c+" "+d);
}
a( "test!", "test!!" ); // 引数dの指定なし
引数が指定されたかチェックする方法
引数が指定されているかどうか、typeof を使用することでチェックできます。
JavaScript
function a( b, c, d ){ // 関数宣言
d = ( typeof d === 'undefined' ) ? "test!!!" : d; // undefinedかどうかチェック
alert(b+" "+c+" "+d);
}
a( "test!", "test!!" ); // 引数dの指定なし
次の式は、引数dに値が渡されなかったとき、デフォルト値として"test!!!"をセットしています。
d = ( typeof d === 'undefined' ) ? "test!!!" : d
ネットで調べると、次の方法が紹介されていることが多いようです。
d = d || "test!!!"
dの値が偽と判定されると、右側の"test!!!"がセットされる式です。
undefineは偽と判定されるので、一見問題のないコードです。
しかし0(ゼロ)やnullも偽と判定されます。
目的があってこれらの値を使用するときは、上のコードは使用できません。
引数のデフォルト値を指定する方法
引数が渡されていないときに、なんらかの決まった値をセットするなら、次の方法でデフォルト値を指定する方が簡単です。
JavaScript
function a( b, c, d = "test!!!"){ // 関数宣言
alert(b+" "+c+" "+d);
}
a( "test!", "test!!" ); // 引数dの指定なし
引数の後にイコールでデフォルト値を指定できます。
function a( b, c, d | = "test!!!" | ){ ・・・コード } | |
↑ | |||
デフォルト値指定 |
ただし途中の引数を省略することはできません。
JavaScript
function a( b, c = "test!!!", d = "test!!!" ){ // 関数宣言
alert(b+" "+c+" "+d);
}
a( "test!", , "test!!!" ); // 引数cの指定なし
エラーで停止します。
Firefox 開発ツール コンソール
! SyntaxError: expected expression, got ','
分割代入やレスト構文を使用した引数
あまり使う人いないけれど分割代入やレスト構文を使用した、ちょっとした小技をいくつかお伝えします。
参考:【JavaScript】 分割代入はどこが便利なのか
参考:【JavaScript】 コード中の「...」は意味があった
引数に名前を付ける
引数にデフォルト値を指定できるなら、デフォルト値と異なるものだけ指定できたら楽ですね。
例えば、次のような関数があったとして…
function a( b = 1 , c = 2 , d = 3 ){ ・・・ }
引数d だけ指定したいと思って次のように関数cを呼び出すと、
a( , , 4);
SyntaxError: expected expression, got ','
エラーになる!
そこでオブジェクトの分割代入を利用すると、変更したいものだけ指定できるようになります。
分割代入で引数を渡す
function a( { b : b = 1 , c : c = 2 , d : d = 3 } ){
console.log( b,c,d);
}
a( { d:4 } );
引数を名前でしていしたようなイメージですね。
関数側では引数で定義したものだけ受け取るので、適当なオブジェクトをそのまま渡すことができます。
オブジェクトを渡して関数側で適当に取得してもらう
let param ={
d:4,
e: "test",
f: function(){ }
};
a( param ); // dのみ引き渡す
この方法だと、呼び出し時に引数を羅列しなくていいので楽ですね。
羅列された引数を配列で受け取る
レスト構文(レストパラメータ)を使用すると、関数呼び出し時に渡された引数を配列変数で受け取ることができます。
レスト構文による配列受け取り
function a( ...b ){
console.log( b ); // Array [ 1 , 2 , 3 ]
}
a( 1 , 2 , 3 );
可変長の引数を受け付けるとき活躍しますね。
配列を展開して引数として渡す
配列の要素を順番に全て渡すとき、一つ一つ添え字をつけて記述するのは面倒です。
スプレッド構文を使うと、手間が省けます。
配列をスプレッド構文で展開して関数に渡す
function a ( b , c ) {
console.log( b , c ); // 1 4
}
let d = [ 1 , 4 ];
a( d[0] , d[1] ); // めんどくさい!
a( ...d ); // とても楽!!
配列の一部だけを展開したいときは、sliceメソッドなどを使用しましょう。
sliceで配列を切り出して渡す
let d = [ 1 , 2 , 3 , 4, 5 ];
a( ...d.slice( 2 , 4 ) ); // 3 4
配列のまま渡し、個別の変数で受け取る
引数定義に [ ] をつけることで、分割代入の関係が成立します。
引数として渡された配列を、そのまま変数に代入できます。
function a ( [ b , c ] ) {
console.log( b , c ); // 1 4
}
a( [ 1 , 4 ] );
引数をargumentsオブジェクトで参照する
関数を呼び出すと、関数内で使用できるargumentsオブジェクトが作成されます。
argumentsオブジェクトには引数が順番にセットされていて、自由に取り出すことができます。
ただし、アロー関数はargumentsオブジェクトを利用できません。
詳しくは、次のページを参考にしてください。
まとめ
僕は今まで単純に引数を羅列しているだけでした。
分割代入などを使用すると便利なパターンがあったら、積極的に利用していきたいですね。
更新日:2020/02/29
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。