関数へミュータブルな値を渡したあと関数内で値を変更する場合の注意点

関数を呼び出すときに引数に値を指定することで関数へ値を渡すことができます。この時ミュータブル(変更可能)な値である配列やオブジェクトを関数へ渡した場合に、関数内で値に対して変更を加える処理を行うと、呼び出した時に指定した値にも変更が反映されます。ここでは JavaScript で関数へミュータブルな値を渡したあと関数内で値を変更する場合の注意点について解説します。

(Last modified: )

イミュータブルな値を関数へ渡す場合

数値や文字列のようにミュータブル(変更不可)な値を引数に指定して関数を呼びだす場合、関数側で引数に対して新しい値を格納しても呼び出し元の値には影響は出ません。

次のサンプルを見てください。

function square(num){
  num = num * num;
  console.log(num);
}

let num = 10;
square(num);
>> 100

console.log(num);
>> 10

関数を呼びだす時に数値が格納された変数を引数に指定しています。関数側では渡されてきた値を二乗したあと変数に格納しなおしてからコンソールへ出力しています。このように関数内で引数に対して新しい値を格納しなおしたとしても、呼び出す時に引数に指定した変数の値には何も影響がでません。

それに対して配列やオブジェクトのようなイミュータブル(変更可)な値を引数に指定して関数を呼びだす場合、関数側で引数に格納された値に対して変更を加えると、呼び出し元の値にも変更が反映されます。

次のサンプルを見てください。

function square(num){
  for (let i = 0 ; i < num.length ; i++){
    num[i] = num[i] * num[i];
  }
  console.log(num);
}

let num = [10, 15, 20];
square(num);
>> [100, 225, 400]

console.log(num);
>> [100, 225, 400]

関数を呼びだす時に配列が格納された変数を引数に指定しています。関数側では渡されてきた配列の各要素の値を二乗したあと配列の値をコンソールへ出力しています。このように関数内で引数に格納されたイミュータブルな値に対して何らかの変更を加えると、呼び出す時に引数に指定した変数の値にも影響がでます。

これは関数を呼びだす時に引数に指定した変数と、呼び出された関数の引数が同じ値を参照しているためで、どちらかが値に対して何らかの変更を加えると、同じ値を参照しているもう片方にも影響がでるためです。イミュータブルな値を引数に指定して関数を呼びだす場合は注意してください。

なお関数内で値に対して変更を加えるのではなく新しい値を代入した場合には、その時点で関数を呼びだす時に引数に指定した変数と、呼び出された関数の引数が別々の値を参照するようになるだけなので、関数を呼びだす時に引数に指定した変数が参照している値には影響はありません。

-- --

JavaScript で関数へミュータブルな値を渡したあと関数内で値を変更する場合の注意点について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。