JavaScript原型:是否为单个原型对象?
我不太懂JavaScript原型。以这段代码为例:JavaScript原型:是否为单个原型对象?,javascript,oop,subclass,Javascript,Oop,Subclass,我不太懂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
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]”?!如果原始原型对象(新类(“proto_类”)正在修改,那么为什么asdf变量不保持“changed_asdf”?如果不是,那么为什么asdf2数组包含“changed_asdf2”?此外,如何确保每个新的子类()实例包含一个新的类()实例,如C++和java?< /p> < p>这是因为您编写了
SubClass.prototype = new Class("proto_class");
您正在创建的原型类的一个实例。您想要的是创建一个子类,该子类继承其父类的原型。正如David Flanagan在其(§9.5)中所示,您必须使用辅助函数来创建具有指定原型的新对象:
function heir(p) {
function f(){} // dummy constructor function
f.prototype = p; // specify prototype object we want
return new f(); // create and return new object
}
(Crockford调用此函数对象。在所谓的之后创建,但请不要这样做,因为这样做。)
在子类构造函数中,必须将this
设置为当前对象的类构造函数:
function SubClass() {
// call the parent's constructor with
// `this` set to the current scope
Class.call(this, "proto_class");
}
最后,但并非最不重要的一点是,您只重置Class.asdf2
一次,但不重置Class
或子类的构造函数。因此添加this.asdf2=[]代码>到其中一个构造函数
完整的代码现在是:
function heir(p) {
function f(){} // dummy constructor function
f.prototype = p; // specify prototype object we want
return new f(); // create and return new object
}
function Class(asdf) {
if (typeof asdf != 'undefined')
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() {
// call the parent's constructor with
// `this` set to the current scope
Class.call(this, "proto_class");
this.asdf2 = [];
}
SubClass.prototype = heir(Class.prototype);
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);
那是因为你写作
SubClass.prototype = new Class("proto_class");
您正在创建的原型类的一个实例。您想要的是创建一个子类,该子类继承其父类的原型。正如David Flanagan在其(§9.5)中所示,您必须使用辅助函数来创建具有指定原型的新对象:
function heir(p) {
function f(){} // dummy constructor function
f.prototype = p; // specify prototype object we want
return new f(); // create and return new object
}
(Crockford调用此函数对象。在所谓的之后创建,但请不要这样做,因为这样做。)
在子类构造函数中,必须将this
设置为当前对象的类构造函数:
function SubClass() {
// call the parent's constructor with
// `this` set to the current scope
Class.call(this, "proto_class");
}
最后,但并非最不重要的一点是,您只重置Class.asdf2
一次,但不重置Class
或子类的构造函数。因此添加this.asdf2=[]代码>到其中一个构造函数
完整的代码现在是:
function heir(p) {
function f(){} // dummy constructor function
f.prototype = p; // specify prototype object we want
return new f(); // create and return new object
}
function Class(asdf) {
if (typeof asdf != 'undefined')
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() {
// call the parent's constructor with
// `this` set to the current scope
Class.call(this, "proto_class");
this.asdf2 = [];
}
SubClass.prototype = heir(Class.prototype);
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);
这是因为asdf2
是Class.prototype
上的可变数组。该数组由委托给该原型的所有实例共享。如果希望每个实例都有一个单独的asdf2
,则必须以某种方式将其分配给this.asdf2
请注意,您分配了this.asdf
,但从未分配this.asdf2
,您只需将其推到现有数组
var house = {nice: true};
var me = {home: house};
var roomie = {home: house};
// Now roomie has a party and trashes the place.
roomie.home.nice = false;
//and how's my house?
me.home.nice === false;
// because house is shared.
在本例中,共享house
与共享问题中的asdf2
相同。这是因为asdf2
是Class.prototype
上的可变数组。该数组由委托给该原型的所有实例共享。如果希望每个实例都有一个单独的asdf2
,则必须以某种方式将其分配给this.asdf2
请注意,您分配了this.asdf
,但从未分配this.asdf2
,您只需将其推到现有数组
var house = {nice: true};
var me = {home: house};
var roomie = {home: house};
// Now roomie has a party and trashes the place.
roomie.home.nice = false;
//and how's my house?
me.home.nice === false;
// because house is shared.
本例中共享house
与问题中共享asdf2
相同