1 <script> 2 var fun1 = function(){ 3 this.name = 'peter'; 4 return { 5 name: 'jack' 6 }; 7 } 8 var p1 = new fun1(); 9 console.log(p1.name)//jack 10 11 var fun2 = function(){ 12 this.name = 'peter'; 13 return 'jack'; 14 } 15 var p2 = new fun2(); 16 console.log(p2.name)//peter 17 </script>
1 <script> 2 var fun = function(){} 3 fun.prototype = { 4 info : { 5 name : 'peter', 6 age : 25 7 } 8 } 9 10 var a = new fun(); 11 var b = new fun(); 12 a.info.name = 'jack'; 13 b.info.name = 'tom'; 14 console.log(a.info.name)//tom 15 console.log(b.info.name)//tom 16 </script>
1 var a = {"x": 1}; 2 var b = a; 3 a.x = 2; 4 b.x; //2 5 6 a = {"x":3}; 7 b.x;//2 8 a.x = 4; 9 b.x;//2
首先定義一個對象a,有一個屬性x,值為1。接着讓b = a,這一步的結果就是a和b指向了同一個對象。
在內存中,對象的存儲和基本數據類型不同。基本數據類型直接保存在棧里,a = 1,b = 1,在棧里會保存兩份1,分別賦值給a和b。修改a或b,對另一個變量不會有什么影響。
對象則不然,變量a和b如果被賦值對象,a和b實際上保存的只是對象的地址,而且a和b還是被存儲在棧里,同時a和b的地址是相同的。但對象是在堆里保存,且只保存一份,對象的地址就是a和b的值,a和b都指向同一個對象。這與C里面的指針類似,修改指向同一個對象的任何一個變量,與之引用同一對象變量很快就會發生同樣的變化。如下圖:
所以現在的情況就是,a和b都指向了堆中的一個對象,這個對象的屬性x值是1。那么a.x = 1,b.x自然也等於1。
1 |
a.x = 2 |
接下來發生一件事情,a修改了對象的x屬性為2,這個變化反映到了堆中:
看,a和b還是指向了同一個對象,只不過對象中的x屬性值變成了2。這一變化b很快就發現了,所以你再去訪問b.x,實際上就是訪問堆中的對象的x屬性,也就是2。
1 |
a = {"x":3}; |
再后來,為a賦值了一個新的對象,雖然它也有一個屬性x,但它確實是一個新對象!那么內存堆中發生了什么呢?首先,堆中原有的對象(x = 2的那個)還在那里。因為新建了一個對象(x = 3的),堆中就會出現一個新的對象,與原來的對象毫無關系。同時,b並沒有變化,它還指向原有的對象(x = 2),但a指向原來的對象的地址卻發生了變化,它指向了x = 3的這個新對象。
a的地址變了,同時a和原來的對象也沒有指向關系了,它指向了新的對象,這個新對象的x = 3。而b對象沒有任何變化,它還堅守着自己的對象,對象的x屬性是2。
1 |
a.x = 4; |