为什么重置原型不会从对象中删除属性?

时间:2013-05-22 14:53:14

标签: javascript inheritance prototype

我试图了解javascript原型设计&可能继承,但我肯定遗漏了一些东西。让我们从简单的构造函数(函数Counter())开始,添加对象的简单属性和实例化:

function Counter() { this.a = "first"; };
Counter.prototype.b = "second";
var counter = new Counter();

此时,counter.a返回“第一个”,counter.b返回“第二个”,counter.c当然是undefined,这一切都是可以理解的。让我们为构造函数的原型添加另一个属性:

Counter.prototype.c = "third";  

现在,counter.c将返回“第三”。但是......我们已经改变了主意,让我们摆脱这些属性:

Counter.prototype = {};

使用简单的逻辑,在覆盖counter原型的prototype属性时,我们会丢失之前添加到Counter.prototype的counter的属性。但事实并非如此 - counter.c返回“第三”。我迷失在这里。所以...让我们尝试覆盖价值:

Counter.prototype.c = "fourth hohoho";

没有任何变化,counter.c仍然返回“第三”。

为什么删除属性没有成功?我错过了什么?

3 个答案:

答案 0 :(得分:11)

创建对象时,原型对象的引用将添加到原型中。

您可以扩充该原型对象,并且由于实例共享引用,这些更改将反映在任何现有实例中。

但是,如果覆盖原型对象,之前创建的实例仍然保留对原始原型对象的引用。

与此代码的内容相同:

var a = {};
var b = a;

a.foo = 'bar';    // augment 'a'
b.foo === 'bar';  // true

a = {};           // overwrite 'a'
b.foo === 'bar';  // still true

答案 1 :(得分:8)

您可以动态地添加/删除原型对象中的属性,但不能替换已创建的实例的原型对象。在您的示例中,在替换构造函数的prototype属性之后创建的实例将获得新的原型,但之前创建的实例将保留对前一个对象的引用。

如果要从原型中清除某些属性,请使用delete运算符从原始对象中删除它们:

delete Counter.prototype.c;

答案 2 :(得分:0)

你确定吗?尝试:



function fa () {this.a=1}
var fb = new fa ();
fa.a = 2;
fa.prototype.a = 3;
var fc = new fa ();
console.log (fa.a, fb.a, fc.a);



 从你说的应该打印2 1 3但它打印2 1 1