JavaScriptで関数 functionを呼び出す際に、引数に既に定義してある変数を渡したい場合があります。このとき、変数名を引数 ( ) の中に記述するだけでは処理が思ったとおりに行きません。
ここでは、引数に対して既に定義してある変数を渡す方法と注意点についてまとめています。
結論 { } を使う
結論から言うと、引数の中で { } を使用します。
ここで重要なポイントは、呼び出す関数(function)も呼び出される関数(function)のどちらにも引数の中で { } をつけるということです。
実例 解説
実例として、callという関数の中で、helloという別の関数を呼び出す場合は以下のようになります。
function hello( { greeting, name } ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
function call (){
let name1 = "ジョニー";
let greeting1 = "Good Morning";
hello( { name: name1, greeting: greeting1 } )
}
//関数callを実行
call();
//実行結果
//ジョニーさんGood Morning。
以下で簡単に解説していきます。
まず関数callの中で呼び出した hello についてです。
hello( { name: name1, greeting: greeting1 } )
ここでは、helloという関数を実行するときに、引数に「name」という名前をつけ、値として変数「name1」を渡しています。
つまり上記では、引数名「name」の値は「ジョニー」となります。
引数名「greeting」は、値として変数「greeting1」が入ります。
つまり上記では、引数名「greeting」の値は「Good Morning」となります。
つづいて、実際に呼びだす関数helloでの処理を見ていきます。
function hello( { greeting, name } ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
名前を指定した引数を受け取るには、同じく引数の中で { } を使って、変数名を指定し受け取る準備をしておきます。
引数「greeting」には受け取った値「Good Morning」が入り、引数「name」には「ジョニー」が入ります。
このため、console.logで出力する実行結果は「ジョニーさんGood Morning。」となります。
ポイントとしては、引数での指定が「greeting」→「name」の順番。一方、let reply = name + "さん" + greeting + "。";
で使用している変数が「name」→「greeting」の順であるにも関わらず、きちんと指定した変数の値が入っています。(呼び出した順になっていない)
省略形
なお、引数名(キー名)と渡す変数が一致する場合 { greeting: greeting } を { greeting } のように省略できます。
このため、function hello( { greeting, name } )
で指定している引数は省略形となっています。
function hello( { greeting, name } )
↑↓ 同じ
function hello( { greeting: greeting, name: name } )
つまり、以下のように記述してもまったく同じ処理となります。
function hello( { greeting: greeting, name: name } ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
function call (){
let name1 = "ジョニー";
let greeting1 = "Good Morning";
hello( { name: name1, greeting: greeting1 } )
}
//関数callを実行
call();
//実行結果
//ジョニーさんGood Morning。
よく見る省略形(引数名(キー名)と変数が一致する場合)
引数に名前をつけて変数を渡す場合に、呼び出す関数と呼び出される関数の中で使用する変数は同じものを使用しているのが一般的です。
このため、以下のような記述をよく見かけます。
function hello( { greeting, name } ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
function call (){
let name = "ジョニー";
let greeting = "Good Morning";
hello( { name, greeting } )
}
//関数callを実行
call();
//実行結果
//ジョニーさんGood Morning。
どちらも、( { greeting: greeting, name: name } ) と ({ name: name, greeting: greeting, } )が省略された形となっています。
引数名の指定する順番に注意
引数に名前をつけて関数を実行する場合は省略形を使うことがほとんどなので、引数の受け渡し順序をあまり気にすることはありません。
ここではもう少し深い理解のために、受け渡し順序に注目してみます。
name1, name2, name3 および、greeting1, greeting2, greeting3が出てくる以下の関数があるとします。
function hello( { greeting2: greeting3, name2: name3 } ) {
let reply = name3 + "さん" + greeting3 + "。";
console.log( reply );
}
function call (){
let name1 = "ジョニー";
let greeting1 = "Good Morning";
hello( { name2: name1, greeting2: greeting1 } )
}
//関数callを実行
call();
//実行結果
//ジョニーさんGood Morning。
変数の定義
まず関数callを実行すると、変数 name1 と greeting1を定義します。
let name1 = "ジョニー";
let greeting1 = "Good Morning";
引数に名前をつけて渡す
続いて、呼び出す関数helloの引数に定義した変数を渡します。
hello( { name2: name1, greeting2: greeting1 } )
ここでポイントは、「name2: name1」のように、引数名「name2」の値に変数「name1」を格納して渡すという事です。
同様に引数名「greeting2」の値に変数「greeting1」を格納して渡します。
引数を受け取る
続いて、実際に実行する関数helloで、渡された引数を受け取ります。
function hello( { greeting2: greeting3, name2: name3 } ) {
let reply = name3 + "さん" + greeting3 + "。";
console.log( reply );
}
ここが一番混乱するポイントになるのですが、受け取る時の順番は「引数名: 変数名」となります。引数名を変数にしてはいけません。
hello( { greeting2: greeting3, name2: name3 } )
受け渡しの流れを見るために、nameに注目してみます。
(1)まず変数name1を定義します。
let name1 = "ジョニー";
(2)引数名name2の値として、定義した変数を渡します。
{ name2: name1 }
(3)引数名name2を受け取り、変数name3に格納します。
{ name2: name3 }
(4)変数name3を使用します。
let reply = name3 + "さん" + greeting3 + "。";
順番を間違うとエラーになる
呼び出す関数の中で、引数名と変数名を逆にするとエラーになります。
function hello( { greeting3: greeting2, name3: name2 } ) {
let reply = name3 + "さん" + greeting3 + "。";
console.log( reply );
}
function call (){
let name1 = "ジョニー";
let greeting1 = "Good Morning";
hello( { name2: name1, greeting2: greeting1 } )
}
//関数callを実行
call();
//出力結果(エラー)
let reply = name3 + "さん" + greeting3 + "。";
^
ReferenceError: name3 is not defined
変数「name3」を呼び出そうとしたところ、そのような変数は存在しないというエラーです。
それもそのはずで、下記のように関数を実行するときに、引数名「name3」は指定しているものの、変数「name3」は指定していないためです。(ややこしいですね、、)
function hello( { greeting3: greeting2, name3: name2 } )
よくあるエラーの実例
その他によく見かけるエラーとしては、呼び出す関数か呼び出される関数の一方しか { } を使っていない(引数名を指定していない)場合があります。
実例1 呼び出す関数で { } を使用していない。
function hello( { greeting, name } ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
function call (){
let name = "ジョニー";
let greeting = "Good Morning";
hello( greeting, name );
}
//関数callを実行
call();
//実行結果
undefinedさんundefined。
実行結果は「undefinedさんundefined。」となってしまいます。
関数callの中で hello( greeting, name )
とし、引数名を指定せずに、変数「greeting」と「name」をそのまま渡しています。
一方、実行される側の関数helloでは、hello( { greeting, name } )
として引数名「greeting」と「name」だけを受け取ると指定しています。
引数名を指定して渡された変数はないので、どちらも「undefined」となります。
実例2 呼び出される関数で { } を使用していない。
function hello( greeting, name ) {
let reply = name + "さん" + greeting + "。";
console.log( reply );
}
function call (){
let name = "ジョニー";
let greeting = "Good Morning";
hello( { name, greeting } )
}
//関数callを実行
call();
//実行結果
undefinedさん[object Object]。
実行結果は「undefinedさん[object Object]。」となってしまいます。
関数callの中で hello( { greeting, name } )
とし、引数名を指定して、変数「greeting」と「name」を渡しています。
つまり以下を渡そうとしているということです。
{ name: 'ジョニー', greeting: 'Good Morning' }
一方、実行される側の関数helloでは、hello( greeting, name )
として引数名を指定していません。
最初に渡された引数が変数「greeting」に入ります。つまり { name: 'ジョニー', greeting: 'Good Morning' }
が入るわけです。これは文字列に直すと [object Object] として表示されます。
2つ目の引数「name」には受け取るものが何もないので、「undefined」となります。
このため実行結果は以下のようになります。
undefinedさん[object Object]。