我有一个班级的两个实例。在第一个实例中设置属性也会为第二个实例设置它。为什么?它不应该。该物业不是“原型物业”。
检查下面的代码,Peter Griffin会怎么样? 创建了两个对象并命名为“Peter Griffin”和“Roger Moore”,但警报框将显示“Peter Moore”和“Roger Moore”。彼得格里芬怎么了?
var BaseClass = function(){
this.name = "";
this.data = {};
this.data.lastname = "";
}
var ExtendedClass = function(){
this.setName = function(fname, lname){
this.name = fname;
this.data.lastname = lname;
}
this.hello = function(){
alert("Full name: " + this.name + " " + this.data.lastname);
}
}
ExtendedClass.prototype = new BaseClass();
pilot = new ExtendedClass();
driver = new ExtendedClass();
pilot.setName("Peter", "Griffin");
driver.setName("Roger", "Moore");
pilot.hello(); // Full name: Peter Moore
driver.hello(); // Full name: Roger Moore
答案 0 :(得分:1)
您未在this.data= {}
构造函数中分配新的ExtendedClass
。因此,每个ExtendedClass
实例都从其原型data
实例继承BaseClass
对象。这是一个Object
!从一个实例写入lname
,所有实例都会看到更改。
JavaScript的构造函数和原型是混乱的混乱。您通常不希望使用实例(使用缺少的参数构造)作为类的基础。这只是导致的许多错误之一。
此外,在ExtendedClass
构造函数中,为每个实例编写一个新的单独hello
方法,而不是像通常使用原型那样在实例之间共享相同的函数。
你可能对一些写得不好的JS OOP教程代码感到困惑,这并不奇怪,因为那里的大多数例子都非常糟糕。有关JS中OO的各种更一致的方法的讨论,请参阅this question。