使用原型时,JavaScript对象会被覆盖

使用原型时,JavaScript对象会被覆盖,javascript,object,prototype,Javascript,Object,Prototype,我有一个Pers(on)和一个雇员,他们来自Pers Pers = function(options){ this.Name; this.ID; this.init = function(options){ this.Name=options.Name; this.ID=options.ID; } } Employee = function(options){ this.Sal; this.init = function(options){ th

我有一个Pers(on)和一个雇员,他们来自Pers

Pers = function(options){
  this.Name;
  this.ID;
  this.init = function(options){
    this.Name=options.Name;
    this.ID=options.ID;
  }
}

Employee = function(options){
  this.Sal;
  this.init = function(options){
    this.Sal=options.Sal;
    this.__proto__.init(options);
  }
  this.init(options);
}

Employee.prototype=new Pers();
现在当我创建新对象时

var o=new Employee({Name:"Nik",ID:"1",Sal:100});
var p=new Employee({Name:"Tanja",ID:"2",Sal:200});
提醒他们的名字,我会得到两次“Tanja”

有人有主意吗

this.__proto__.init(options);
将调用原型上的
init
方法,原型本身为
this
,导致您修改原型。试一试

this.__proto__.init.apply(this, [options]);
编辑

要避免
\uuuu proto\uuuu
,可以在对prototype init函数进行阴影化之前保存对该函数的引用:

Employee = function(options){
  this.Sal;
  var protoInit = this.init;
  this.init = function(options){
    this.Sal=options.Sal;
    protoInit.apply(this, [options]);
  }
  this.init(options);
}

您在错误的范围内调用
init
。试试这样的

function Person(opt) {
    this.name = opt.name;
    this.id = opt.id;
}

function Employee(opt) {
    Person.call(this, opt);
    this.sal = opt.sal;
}

Employee.prototype = Object.create(Person.prototype, {});
现在,您可以设置
Person.prototype
Employee.prototype
的属性,它们的行为应符合预期


这避免了使用不推荐的hacky属性(
\uuuuuu proto\uuuuuu
),而且应该更加清晰
Object.create
用于使用超级构造函数的原型生成实例,而不实际调用超级构造函数(无需调用
init
调用)。您可以在执行此操作时包括半标准属性定义,如
super
constructor
,就像许多库的
继承实现一样。

非常确定您不应该再使用
\uuuu proto\uuu
调用(此,选项)
在这种情况下可能更好这不起作用,当我创建新对象时:var o=newemployee({name:“Nik”,id:“1”,sal:100});var p=新雇员({姓名:“Tanja”,id:“2”,sal:200});o、 将找不到名称。我做错了什么?在我匆忙地重新编写而没有
init
,我犯了与您相同的错误。答案已编辑。