参照型の値を変数へ代入

広告

変数に値を代入する時、数値や論理値であった場合には値そのものを変数に格納します。また変数を別の変数に代入した場合には、元の変数に格納されていた値が複製されて新しい変数に格納されます。

var num1;
num1 = 20;     // 変数に20という数値を格納する

var num2;
num2 = num1;   // 変数num1に格納されている数値20を複製し、変数num2にも格納する

それに対してオブジェクト型の値を変数に格納する場合には、オブジェクトはある場所に一度格納され、その位置情報だけを変数に格納します。例えばオブジェクト型の配列を例に考えてみます。

var obj1;
obje1 = ['東京都', '大阪府', '北海道'];

この時、配列の値である['東京都', '大阪府', '北海道']がメモリ上のどこかに作成されます。そしてそのメモリの場所だけが変数obj1に格納されることになります。

このように位置情報だけが変数に格納されていたとしても、変数を使用する場合は格納されている位置の情報を使ってオブジェクトの実体を参照したり変更を加えたりすることができますのであまり意識することはありません。

ただしオブジェクト型の値が格納された変数を別の変数に代入した場合には注意が必要です。

var obj1;
obj1 = ['東京都', '大阪府', '北海道'];

var obj2;
obj2 = obj1;

変数obj2に対して変数obj1を代入していますが、変数obj1にはメモリ上の位置が格納されていました。その為、変数obj2に格納されるのも変数obj1に格納されていたメモリ上の位置となります。つまり実体となるオブジェクトはメモリ上に1つだけ存在し、そのメモリ上の位置が二つの変数に格納されることになります。

基本データ型の場合には、値の実体そのものが変数に格納されていましたので、別の変数に代入した場合には値そのものが複製され値は同じだけど別のものとして格納されています。それに対してオブジェクト型の値の場合には、どちらの変数も同じ1つのオブジェクトを見ているということです。

その為、どちらの変数からでも同じオブジェクトに対して変更を加えることができますし、どちらかの変数によって加えられた変更は他の変数にも影響を与えることになります。次の例を見てください。

var obj1;
obj1 = ['東京都', '大阪府', '北海道'];

var obj2;
obj2 = obj1;

obj2[2] = '福岡県';

変数obj2を使って配列の要素の値を変更すると、変数obj1の格納されている値を参照すると変更が加えられていることが確認できます。

このように基本データ型の値を変数に格納した場合と、オブジェクト型の値を変数に格納した場合では考え方が異なりますので注意が必要です。(なお文字列の場合は論理的にはオブジェクト型に近いのですが、挙動としては基本データ型の場合と同じと考えておけば間違いありません)。

サンプルコード

では簡単なサンプルで試してみます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>JavaScript テスト</title>
</head>
<body>

<script type="text/javascript" src="./js/script7_1.js">
</script>

</body>
</html>
/* JavaScriptサンプル */

var obj1;
obj1 = ['東京都', '大阪府', '北海道'];

var obj2;
obj2 = obj1;

document.write("<p>obj1 : " + obj1 + "</p>");
document.write("<p>obj2 : " + obj2 + "</p>");

obj1[1] = '神奈川県';

document.write("<p>obj1 : " + obj1 + "</p>");
document.write("<p>obj2 : " + obj2 + "</p>");

obj2[2] = '福岡県';

document.write("<p>obj1 : " + obj1 + "</p>");
document.write("<p>obj2 : " + obj2 + "</p>");

上記を実際にブラウザ見てみると次のように表示されます。

p7-1

どちらの変数を使って配列に対して変更を加えても、もう片方の変数にも影響が及んでいることが確認できます。

( Written by Tatsuo Ikura )