每个实例都有一个指向构造函数原型的链接,使用它创建它。所以每个实例都共享原型成员。如果通过一个实例对共享原型成员进行更改,则会将其反映到所有其他实例。为什么这似乎不适用于原始类型,如下所示:
//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
正如您所看到的,更改原始成员的值会在value
上创建一个名为obj1
的新实例属性,而不是在原型中覆盖相同的命名属性。因此,当访问obj1.value
属性时,它返回掩盖原型属性的实例属性。这就是为什么两个实例实例显示value
的不同值。
然而,从上面可以看出,这种不参考类型的行为不同。为什么呢?
答案 0 :(得分:1)
当您写入对象中的属性时,新值将存储在对象上,而不是原型。
你有这样的数组问题:
获取存储在obj1上的数组,并修改数组: obj1.arr.push( “黑色”);
在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直接链接到proto:
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
答案 1 :(得分:1)
您正在推送数组,而不是像使用原始值一样分配新数组。这将按预期工作:
obj1.value = 1;
obj1.arr = [];
请注意,设置值永远不会在原型上设置,而是在对象本身上设置。
答案 2 :(得分:0)
obj1.value = 1;
这创建了obj1
的新属性“值”,并且没有使原型变异。这就是obj2.value
返回与原型中最初设置相同的旧值的原因。
如果您想通过obj1
修改原型,以使其也影响该函数的所有其他实例,请通过沿着原型链进行更改来更改属性:
obj1.__proto__ === OBJTYPE.prototype; //true
obj1.__proto__.value = 1;
obj1.value; //1
obj2.value; //1