プリミティブ
はい、今回も、JavaScript学習経過で学んだことで特徴的なことを備忘録で書いておきます。
まずは、次のカンタンなプログラム。
var a = 0;
var b = a;
console.log(a);
console.log(b);
b =12;
console.log(a);
console.log(b);
最初に、aには0を、bにはaを代入して表示します。
すると、当然、
0
0
と表示されます。そのままですね。
そのあと、bには1を代入して、改めて表示すると、
0
1
と表示されます。bだけ中身を変えたので、aはのまま。これも当然です。
こう言う、プリミティブと呼ばれる型(数字とか文字とかtrueとかfalseとか)の場合は、変数には値がそのまま渡されます。
これが、古いボクの頭での常識でした。
オブジェクト
一方、古いボクの頭に無かった知識である、オブジェクトだと話が違います。
オブジェクトの一種である配列を使ってみましょう。
var c = [0, 1];
var d = c;
console.log(c);
console.log(d);
d[0] = 1;
console.log(c);
console.log(d);
最初にcに[0, 1]を代入し、dにはcを代入しています。
これで、cとdを表示するので、
[0, 1]
[0, 1]
と表示されます。ここまではわかりますね。
で、そのあと、dの最初の値であるd[0]に1を代入しています。
そして、cとdをあらためて表示すると、何と、
[1, 1]
[1, 1]
となってしまいます。
つまり、d[0]を変えたら、c[0]も変わってしまいました。
この理屈は、実は、オブジェクトの場合は、cとかdと言う変数とは別に単独で存在していて、cやdはそれを参照しているからです。
つまり、最初に、
var c = [0, 1];
と宣言した時点で、
[0, 1]と言うオブジェクトが作られます。
そして、cはそのオブジェクトを見るわけです。
次に、
var d = c;
と書いた時点で、dもまたcと同じ[0, 1]と言うオブジェクトを見ます。
要は、
[0, 1]
c
d
の3つが存在すると考えればわかりやすいでしょう。
cもdもオブジェクトである、[0, 1]を見ている状態です。
そして、
d[0] = 1;
とすると、[0, 1]と言うオブジェクトの最初の値である0が1に書き換わります。
[1, 1]
に変化するんですね。
そして、その[1, 1]と言うオブジェクトを、cもdも見ているので、cもdも両方とも、
[1, 1]
と表示されるわけです。
プリミティブ型の場合は、値はそのまま渡される。
オブジェクトの場合は、参照元が渡される。
初心者には、ややこしいですねえ。
ええ、ボクにとって、ややこしいです。
しかし、それがJavaScriptの仕様。
知っておくしかありません。
cとdとを別々に扱う場合は、元のオブジェクトも別々に作る必要があります。
そのやり方はいくつかあると思いますが、長くなるので、別の回に書きたいと思います。
この本、読み終えました。