我真的不太理解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"?!如果原始的原型对象(新的类(“proto_class”))正在被修改,那么为什么asdf变量不保持为"changed_asdf"?如果不是,为什么asdf2数组包含"changed_asdf2"?此外,如何确保每个新的SubClass()实例都包含一个新的类()实例,就像在C++和Java中一样?
发布于 2010-08-30 03:33:11
那是因为你写了
SubClass.prototype = new Class("proto_class");您正在创建Class的one instance的原型。您想要的是创建一个继承其父类原型的子类。正如David Flanagan在他的JavaScript: The Definitive Guide (§99.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在所谓的ES5 object constructor property之后调用这个函数Object.create,但请不要这样做,就像这个can be misleading一样。)
在SubClass构造函数中,您必须对类构造函数执行call操作,并将this设置为当前对象:
function SubClass() {
// call the parent's constructor with
// `this` set to the current scope
Class.call(this, "proto_class");
}最后但并非最不重要的一点是,您只能重置Class.asdf2一次,但不能在Class或SubClass的构造函数中重置。因此,将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);发布于 2010-10-20 04:11:53
这是因为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共享相同。
https://stackoverflow.com/questions/3571940
复制相似问题