2012-10-28 154 views
0

每個實例都有一個到創建它的構造函數原型的鏈接。所以每個實例都共享原型成員。如果通過一個實例對共享原型成員進行更改,則會反映到所有其他實例。爲什麼這似乎不符合基本類型工作,因爲可以看到下面:原型中原始類型的行爲

//creating an empty object type 
function OBJTYPE(){}; 

//adding primitive value and reference value as a memeber to 
//the prototype of the object type 
OBJTYPE.prototype.value = 0; 
OBJTYPE.prototype.arr = ["red","green","blue"]; 

//creating instances of the object type 
var obj1 = new OBJTYPE(); 
var obj2 = new OBJTYPE(); 

//outputting the prototype members through both the instances  
document.write(obj1.value + "<br />"); //0 
document.write(obj2.value + "<br />"); //0 
document.write(obj1.arr + "<br />"); //red,green,blue 
document.write(obj2.arr + "<br />"); //red,green,blue 

//changing value of primitive member 
obj1.value = 1; //creates a new instance property 

//modifying the reference type member - pushing a value on the array 
obj1.arr.push("black"); //modifies the prototype property 

//outputting the prototype members through both the instances  
document.write(obj1.value + "<br />"); //1 //.value from instance 
document.write(obj1.__proto__.value + "<br />"); //0 //.value from prototype 
               //works in Firefox, Safari, and Chrome 
document.write(obj2.value + "<br />"); //0 //.value from prototype 

document.write(obj1.arr + "<br />"); //red,green,blue,black 
document.write(obj2.arr + "<br />"); //red,green,blue,black 

正如你可以在上面看到改變原始成員的價值創造,而不是覆蓋同名屬性調用valueobj1一個新的實例屬性,在原型中。因此,當訪問obj1.value屬性時,它會返回屏蔽原型屬性的實例屬性。這就是爲什麼兩個實例顯示不同值value

但是,這不引用類型的行爲不像從上面可以看出。爲什麼?

回答

1

您正在推送到ar不像你用原始值那樣分配一個新的數組。這將如預期:

obj1.value = 1; 
obj1.arr = []; 

需要注意的是從來沒有設置一個值上設置的雛形,但對象本身。

+0

很大,但有什麼辦法可以修改基本類型創建這樣沒有實例屬性,但原型屬性被修改 – Mahesha999

+0

沒有因爲原始值沒有任何修改。更準確地說,它們是不可改變的。 – Esailija

+0

多虧了這一點,現在只是脫離主題,我試圖用@提及你,但是當我提交評論時,它刪除了提及。此外,當我點擊@時,它並未向我顯示列表中所有成員的列表彈出窗口,這是用於早期發生的。爲什麼? – Mahesha999

1

當您寫入對象的屬性時,新值將存儲在對象上,而不是原型。

數組的問題你必須是這樣的:

  1. 給我上存儲OBJ1數組,並修改該數組: obj1.arr.push(「黑」);

  2. 撰寫OBJ1的實例的新值: obj1.arr = [1,2,3];

我會擴大,如果你需要我。


是的,有很多方法可以做到這一點,這取決於你需要什麼。

1對我來說最明顯的是你想要相同的對象,在這種情況下,我只是做一個對象。

var obj1 = { 
"arr": [], 
"value": 0 
}; 
// I can garuntee any editing you do on obj1 will be reflected on obj2 
var obj2 = obj1; 

2製作原型存取方法:

function OBJTYPE(){}; 

//adding primitive value and reference value as a memeber to 
//the prototype of the object type 
OBJTYPE.prototype.value = 0; 
OBJTYPE.prototype.arr = ["red","green","blue"]; 
OBJTYPE.prototype.proto = function (name, optValue) { 
if (arguments.length === 2) { 
    return OBJTYPE.prototype[name] = optValue; 
} 

return OBJTYPE.prototype.proto[name]; 
}; 

var obj1 = new OBJTYPE(); 
var obj2 = new OBJTYPE(); 

obj1.proto('value', 1); //on the prototype 
// The rest will behave like desired 

3商店直接鏈接到原:

function OBJTYPE(){}; 

//adding primitive value and reference value as a memeber to 
//the prototype of the object type 
OBJTYPE.prototype.value = 0; 
OBJTYPE.prototype.arr = ["red","green","blue"]; 
OBJTYPE.prototype.proto = OBJTYPE.prototype; 
//creating instances of the object type 
var obj1 = new OBJTYPE(); 
var obj2 = new OBJTYPE(); 

//changing value of primitive member 
obj1.proto.value = 1; //on the prototype 
// The rest will behave like desired 

4最後但並非最不重要的,使用ES5的方法getPrototypeOf

function OBJTYPE(){}; 

OBJTYPE.prototype.value = 0; 
OBJTYPE.prototype.arr = ["red","green","blue"]; 
//creating instances of the object type 
var obj1 = new OBJTYPE(); 
var obj2 = new OBJTYPE(); 

//changing value of primitive member 
Object.getPrototypeOf(obj1).value = 1; //on the prototype 
// The rest will behave like desired 
+0

我更新了我的答案 –

+0

嗯,我的問題是完全不同的。仔細閱讀。無論如何,但你已經提出的要點非常好。 – Mahesha999

+0

我已經讀過你的問題了,就像兩次。我爲什麼回答你的問題,然後你問我是否可以解決這個問題。所以我提供了四項工作......我仍然沒有看到我錯過的問題。但是,那好吧,如果你有你想要的然後代碼在兄弟。 –