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

时间:2012-07-17 16:10:07

标签: javascript object prototype

我有Pers(on)和Employee,他们来自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”。

有人有想法吗?

2 个答案:

答案 0 :(得分:3)

this.__proto__.init(options);

将在原型上调用init方法,原型本身为this,导致您修改原型。尝试

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

修改

为避免__proto__,您可以在隐藏它之前保存对原型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);
}

答案 1 :(得分:2)

您在错误的范围内调用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.prototypeEmployee.prototype的属性,它们应该按预期运行。

这可以避免使用hacky弃用的属性(__proto__),并且应该更加清晰。 Object.create用于使用超级构造函数的原型创建一个实例,而不实际调用超级构造函数(不需要init次调用)。您可以在执行此操作时包含superconstructor等半标准属性定义,就像许多库的inherits实现一样。