Javascript 设置实例类特性将覆盖所有实例中的特性

Javascript 设置实例类特性将覆盖所有实例中的特性,javascript,class,Javascript,Class,我有两个类的实例。在第一个实例中设置属性也会在第二个实例中设置属性。为什么?不应该。该属性不是“原型属性” 检查下面的代码,彼得·格里芬怎么了? 创建了两个对象并命名为“彼得·格里芬”和“罗杰·摩尔”,但警报框将显示“彼得·摩尔”和“罗杰·摩尔”。彼得·格里芬怎么了 var BaseClass = function(){ this.name = ""; this.data = {}; this.data.lastname = ""; } var ExtendedClass

我有两个类的实例。在第一个实例中设置属性也会在第二个实例中设置属性。为什么?不应该。该属性不是“原型属性”

检查下面的代码,彼得·格里芬怎么了? 创建了两个对象并命名为“彼得·格里芬”和“罗杰·摩尔”,但警报框将显示“彼得·摩尔”和“罗杰·摩尔”。彼得·格里芬怎么了

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

ExtendedClass
构造函数中,您不会分配新的
this.data={}
。因此,每个
ExtendedClass
实例都从其原型
BaseClass
实例继承
data
对象。这是单个
对象
!从一个实例向其写入
lname
,所有实例都将看到更改

JavaScript的构造函数和原型是一团混乱。您通常不希望使用实例(用缺少的参数构造)作为类的基础。这只是将导致的众多错误之一

另外,在
ExtendedClass
中,构造函数向每个实例编写一个新的、单独的
hello
方法,而不是像通常使用原型那样在实例之间共享相同的函数

您可能已经被一些编写糟糕的JS OOP教程代码弄糊涂了,这并不奇怪,因为大多数示例都非常糟糕。有关JS中各种更一致的OO方法的(长时间)讨论,请参阅