JavaScript 原型设计:是否单一原型对象?
我不太了解 JavaScript 原型设计。以这段代码为例:
function Class(asdf) {
if(typeof(asdf) == 'undefined') {
} else {
this.asdf = asdf;
}
}
Class.prototype.asdf = "default_asdf";
Class.prototype.asdf2 = [];
Class.prototype.change_asdf = function() {
this.asdf = "changed_asdf";
this.asdf2.push("changed_asdf2");
}
function SubClass() {
}
SubClass.prototype = new Class("proto_class");
SubClass.prototype.constructor = SubClass;
test1 = new SubClass();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test1.change_asdf();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test2 = new SubClass();
alert("test2 asdf: " + test2.asdf + " " + test2.asdf2);
第一个警报按预期打印“proto_class []”。第二个警报打印“changed_asdf [changed_asdf2]”,也符合预期。但是为什么第三个警报打印“proto_class [changed_asdf2]”?!如果原始原型对象(new Class(“proto_class”))被修改,那么为什么asdf变量不保持“changed_asdf”?如果不是,那么为什么 asdf2 数组包含“changed_asdf2”?此外,如何确保每个新的 SubClass() 实例都包含一个新的 Class() 实例,就像在 C++ 和 Java 中一样?
I don't really get JavaScript prototyping. Take this code, for instance:
function Class(asdf) {
if(typeof(asdf) == 'undefined') {
} else {
this.asdf = asdf;
}
}
Class.prototype.asdf = "default_asdf";
Class.prototype.asdf2 = [];
Class.prototype.change_asdf = function() {
this.asdf = "changed_asdf";
this.asdf2.push("changed_asdf2");
}
function SubClass() {
}
SubClass.prototype = new Class("proto_class");
SubClass.prototype.constructor = SubClass;
test1 = new SubClass();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test1.change_asdf();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test2 = new SubClass();
alert("test2 asdf: " + test2.asdf + " " + test2.asdf2);
The first alert prints "proto_class []", as expected. The second alert prints "changed_asdf [changed_asdf2]", also as expected. But why does the third alert print "proto_class [changed_asdf2]"?! If the original prototype object (new Class("proto_class")) is being modified, then why doesn't the asdf variable remain "changed_asdf"? And if it isn't, then why does the asdf2 array contain "changed_asdf2"? Furthermore, how do I make sure that each new SubClass() instance contains a fresh instance of Class(), as in C++ and Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为您写道
您正在创建
Class
的一个实例的原型。您想要的是创建一个继承其父类原型的子类。正如 David Flanagan 在他的 JavaScript:权威指南 (§ 9.5 ),你必须使用一个辅助函数来创建一个具有指定原型的新对象:(Crockford调用这个函数
Object.create
,在所谓的ES5 对象构造函数属性,但请不要这样做,因为这个 可能会产生误导。)在子类构造函数中,您必须使用
this
类构造函数> 设置为当前对象:最后但并非最不重要的一点是,您只需重置
Class.asdf2
一次,而不是在Class
或SubClass< 的构造函数中重置/代码>。因此,将
this.asdf2 = [];
添加到其中一个构造函数。完整的代码现在如下:
It's because you write
you are creating a prototype of one instance of
Class
. What you want is to create a sub-class that inherits from its parent's prototype. As David Flanagan shows in his JavaScript: The Definitive Guide (§ 9.5), you have to use a helper function to create a new object with a specified prototype:(Crockford calls this function
Object.create
, after the so-called ES5 object constructor property, but please don't do this, as this can be misleading.)Within the SubClass constructor, you have to call the Class constructor with
this
set to the current object:And last, but not least, you only reset
Class.asdf2
once, but not in the constructor function ofClass
orSubClass
. So addthis.asdf2 = [];
to one of the constructors.The complete code now reads:
这是因为
asdf2
是Class.prototype
上的可变数组。该数组由委托给该原型的所有实例共享。如果您希望每个实例都有一个单独的asdf2
,则必须通过某种方法将其分配给this.asdf2
。请注意,您分配了
this.asdf
,但从未分配this.asdf2
,您只是将其推送到现有数组。本例中
house
的共享与问题中asdf2
的共享相同。This is because
asdf2
is a mutable array onClass.prototype
. That array is shared by all instances that delegate to that prototype. If you want each instance to have a separateasdf2
, you have to assign it tothis.asdf2
in some method.Note that you assign
this.asdf
, but you never assignthis.asdf2
, you just push on to the existing array.The sharing of
house
in this example is the same as the sharing ofasdf2
in the question.