9

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

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

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

Counter.prototype.c = "third";  

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

Counter.prototype = {};

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

Counter.prototype.c = "fourth hohoho";

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

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

4

3 回答 3

11

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

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

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

这与此代码发生的情况相同:

var a = {};
var b = a;

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

a = {};           // overwrite 'a'
b.foo === 'bar';  // still true
于 2013-05-22T15:00:48.477 回答
8

You can add/remove properties from a prototype object dynamically, but you can't replace the prototype object of instances that have been already been created. In your example, instances created after you replaced the constructor's prototype property will get the new prototype, but the ones created before that will keep a reference to the former object.

If you want to clear some property from the prototype, remove them from the original object, using the delete operator:

delete Counter.prototype.c;
于 2013-05-22T14:58:35.247 回答
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

于 2015-01-09T18:20:22.073 回答