我试图了解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仍然返回“第三”。
为什么删除属性没有成功?我错过了什么?
答案 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);