JavaScriptで、オブジェクトのプロパティのオブジェクト(配列等)のインスタンスが共有される
例1:
(オブジェクト同士を"==="で比較すると、インスタンスが同じなら真、異なるなら偽になる。)
function Hoge() { this.val; this.arr; } var hoge; hoge = new Hoge(); hoge.val=1; hoge.arr.push(null); var hage; hage = new Hoge(); hage.val=9; hage.arr.push(null); alert('hoge.val=' + hoge.val + '\nhoge.arr.length=' + hoge.arr.length + '\n' + 'hage.val=' + hage.val + '\nhage.arr.length=' + hage.arr.length + '\n' + 'hoge.valとhage.valは' + (hoge.val===hage.val ? '同一の' : '異なる') + 'インスタンス。' + '\n' + 'hoge.arrとhage.arrは' + (hoge.arr===hage.arr ? '同一の' : '異なる') + 'インスタンス。');
結果1:
hoge.val=1 hoge.arr.length=2 hage.val=9 hage.arr.length=2 hoge.valとhage.valは異なるインスタンス。 hoge.arrとhoge.arrは同一のインスタンス。
これではまったぜ……。どうりで無限ループになるわけだ。
で、別のインスタンスにするには、オブジェクトを生成してから改めて配列プロパティをnew
すればよい。
例2:
function Hoge() { this.val; this.arr; } var hoge; hoge = new Hoge(); hoge.val=1; hoge.arr = new Array(); hoge.arr.push(null); var hage; hage = new Hoge(); hage.val=9; hage.arr = new Array(); hage.arr.push(null); alert('hoge.val=' + hoge.val + '\nhoge.arr.length=' + hoge.arr.length + '\n' + 'hage.val=' + hage.val + '\nhage.arr.length=' + hage.arr.length + '\n' + 'hoge.valとhage.valは' + (hoge.val===hage.val ? '同一の' : '異なる') + 'インスタンス。' + '\n' + 'hoge.arrとhage.arrは' + (hoge.arr===hage.arr ? '同一の' : '異なる') + 'インスタンス。');
結果2:
hoge.val=1 hoge.arr.length=1 hage.val=9 hage.arr.length=1 hoge.valとhage.valは異なるインスタンス。 hoge.arrとhoge.arrは異なるインスタンス。
何故こういう挙動になるかは、JavaScriptで変数やオブジェクトがどのように扱われているか(実装されているか)と、prototype/プロトタイプ チェインを知れば、自然と理解できるはず。