質問: 1. JavaScript の「実引数スコープ」は「ローカルスコープ」? ... JavaScript の実引数では、グローバル変数を参照可能だけど、実引数で定義した変数をグローバルで参照できないので、「ローカルスコープ」? 2. 「仮引数スコープ」と同じ? ... JavaScript の「実引数スコープ」は、「仮引数スコープ」と同じスコープ? 3. 「仮引数スコープ」の値は「ローカルスコープ」で、オブジェクトは「グローバルスコープ」? ... 「仮引数スコープ」は、基本は「ローカルスコープ」だけど、参照型の変数の場合のみ「グローバルスコープ」になる、ということでしょうか?
回答: 結論から言うと、実引数の方はその実引数のスコープで、仮引数はその function 内でのローカルスコープとなります。 仮引数はあくまでもローカルスコープであり、グローバルスコープにはなりません。 Javascript では、function の引数に共有渡し(Call by sharing)で変数が渡されますが、その挙動が混乱を招いているものと思います。 例えば以下の様な場合、 ``` var str = 'string'; var int = 12; function test(text, num) { // 渡した変数(実引数)は変更されない text = 'test'; num = 23; } test(str, int); console.log(str, int); // => 'string', 12 ``` function内部で変数を書き換えたとしても、渡した変数(実引数)に影響を与えませんが、 以下のような場合、影響を与えます。 ``` var hash = {str: 'string', int: 12}; function test(obj) { // 渡した変数(実引数)が変更される obj.str = 'test'; obj.int = 23; } test(hash); console.log(hash); // => {str: "test", int: 23} ``` オブジェクトのメソッドやプロパティにアクセスして変更を行うような場合、その仮引数が実引数と共有される(同じものを見る)ため、実引数のオブジェクトも変更されます。 また、オブジェクトを渡して、関数内で仮引数に別のオブジェクトを代入するような場合は、影響を与えません。 ``` var hash = {str: 'string', int: 12}; function test(obj) { // 渡した変数(実引数)は変更されない obj = {str: 'test', int: 23} } test(hash); console.log(hash); // => {str: 'string', int: 12} ``` 以下の質問を併せて参照ください。 Javascriptの仕様で「オブジェクトは共有渡しで、プリミティブ値は値渡し」と区別しているのか