JavaScriptにおいて、関数やオブジェクトのメソッドに引数を渡す際の取り扱い(Evaluation strategy)についてまとめておきましょう。JavaScriptでは実引数のリファレンスが仮引数にコピーされて渡されと考えるとよいでしょう。この方式を「共有渡し」(Call by sharing)あるいは「参照の値渡し」(call by value where value is the reference copy)などと呼びます。
■ イミュータブルな引数を渡す場合
数値や文字列のようなイミュータブルな値を引数として渡す場合、関数内でその値を変更しても、呼び出しもとには反映されません。
function myFunc1(n) { n = n + 10; // (1) } var num = 10; myFunc1(num); console.log(num); // => 10 (2)
この例では、関数myFuncを呼び出す際に、数値が代入された変数numを引数として渡しています。こうすると実引数numのリファレンスが仮引数nのリファレンスにコピーされます。この状態では変数numと変数nは同じ実体を指し示します。
関数の内部では(1)で仮引数nに10を足して再びnに代入しています。こうすると関数内の変数nのリファレンスは新たに生成された数値を指し示すようになります。したがった実引数のnumと仮引数のnは異なる実体を指し示すようになります。
myFuncを呼び出して、(2)でnumの値を表示すると、関数myFuncの呼び出し前の値である「10」が表示されます。
<◎図 a1>
■ ミュータブルな引数を渡す場合(変更が呼び出しもとに反映されないケース)
ミュータブルな型を引数として渡す場合も同様です。関数内部で引数として渡された変数のリファレンス、つまり参照先を変更してしまった場合には、呼び出しもとの引数の値は変更されません。次の例はミュータブルな型であるDateオブジェクトを引数として渡しています。
function myFunc3(date) { date = new Date(2017, 1, 1); // (1) } var theDate = new Date(2016, 10, 1); myFunc3(theDate); console.log(theDate); // => Tue Nov 01 2016 〜 (2)
この場合 、(1)で新たなDateオブジェクトを生成しそれを引数の変数dateに再代入していますので、リファレンスが変更されます。
関数呼び出し後に、(2)で変数theDateの値を表示すると結果はもとのままです。
<◎図 a2>
■ ミュータブルな引数を渡す場合(変更が呼び出しもとに反映されるケース)
ただし、関数内部で変数のリファレンス自体が変更されない場合には、関数内部で引数値の変更は呼び出しもとの変数に反映されます。引数として渡さされた変数に対して値を変更するメソッドを実行したような場合などです。
次の例はミュータブルな型であるDateオブジェクトを引数に渡し、内部の(1)でsetFullYear()メソッドで年を変更しています。
function myFunc2(date) { date.setFullYear(1950); // (1) } // **関数 var theDate = new Date(2016, 10, 1); myFunc2(theDate); console.log(theDate); // (2) Wed Nov 01 1950 〜
この場合、実引数theDayと仮引数dayのリファレンスは同じ実体を指し示すため、関数内での変更が反映されます。(2)では年が1950になった値が表示されます。

<◎図 a3>
* Quitaに投稿したものと内容は同じです。Quitaで画像サイズの上限で跳ねられたためこちらに画像付きのものをおいておきます。