クラス化して最初に間違え,悩むことは恐らくココに書いていることです.重要なので必ず,読んでください.アラートダイアログに何が表示されるか考えながら読んでみて下さい.
例えば以下のプログラムです.
var r0 = new Rectangle(3, 2);
var r1 = new Rectangle(4, 6);
alert(r0 == r1);
これは,予想通り false が表示されます.では,次はどうでしょう.
var r0 = new Rectangle(1, 1);
var r1 = new Rectangle(1, 1);
alert(r0 == r1);
true が表示されると思いますか?.それは間違いです.やっぱり,false が表示されます.これは中身が同じでも参照している場所が違うためです.では,次はどうだと思いますか?
var r0 = new Rectangle(1, 1);
var r1 = r0;
alert(r0 == r1);
これは true が表示されます.参照している場所が一緒のためです.これらはポインタ(or 参照)と呼ばれる概念がそういう結果を生みます(ここでは説明しません).
これと関連して次のプログラムを見てみましょう.
var r0 = new Rectangle(4, 3);
var r1 = r0;
r0.width = 5;
alert(r1.width);
答えは 4 ではなく,5 です.つまり,r1 = r0 とした時点で r0 と r1 は同じところを参照し,このままではずっと連動してふるまうことになります.意図通りに表示したい(4を表示したい)場合は次のように書きます.
var r0 = new Rectangle(4, 3);
var r1 = new Rectangle(r0.width, r0.height);
r0.width = 5;
alert(r1.width);
こうしておけば,ステータスバーに表示されるのは 4 です.newで新たなインスタンスを作成することが重要です.
最後にもう少し踏み込んだ,誤解しやすいプログラムを示します.swap関数です.
function swap(a, b) {
var temp = a;
a = b;
b = temp;
}
var r0 = new Rectangle(0, 0);
var r1 = new Rectangle(1, 1);
alert(r0.width);
swap(r0, r1);
alert(r0.width);
残念ながらこのプログラムを実行してもr0とr1は入れ替わりません.JavaScriptの関数の参照渡しは,参照そのものではなく,参照しているアドレスの値を渡しているからです.かといって関数の引数に渡すときに,インスタンスそのもののコピーが作成されるわけではありませんので,以下のプログラムは意図した通りに動作します.
function changeValue(a, b) {
a.width = 10;
var temp = b;
temp.width = 100;
}
var r0 = new Rectangle(0, 0);
var r1 = new Rectangle(1, 1);
alert(r0.width);
alert(r1.width);
changeValue(r0, r1);
alert(r0.width);
alert(r1.width);
これらが参照型(object/array/function
)の特徴ですが分かりましたでしょうか?.
Javaの場合は同じ挙動を示すので問題ないですが,C++から飛び込んだ人は戸惑うかもしれません.JavaScriptでインスタンスを扱う場合,常に参照渡し(参照しているアドレスの値渡し.つまり本質的には値渡し)であることを念頭に置いてプログラミングして下さい.
次項からは,これだけでは物足りないという人にもう一歩進んだオブジェクト指向について説明します.