2012-10-28 117 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

我已经读过你的问题了,就像两次。我为什么回答你的问题,然后你问我是否可以解决这个问题。所以我提供了四项工作......我仍然没有看到我错过的问题。但是,那好吧,如果你有你想要的然后代码在兄弟。 –