如何在javascript中继承基类属性并调用基类构造函数?

时间:2013-12-22 07:20:58

标签: javascript inheritance prototypal-inheritance

假设我有一个Employee类:

function Employee(name, age, salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}

function Manager(name, age, salary, management_school_name) {
  ...
}

Manager.prototype = new Employee();
Manager.prototype.constructor = Manager;

在上面的代码中,我想利用Employee封装nameagesalary这一事实。

那么我应该如何处理重复的参数?

5 个答案:

答案 0 :(得分:3)

function Employee(name, age, salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}

function Manager(name, age, salary, management_school_name) {
  Employee.call(this,name,age,salary); //Call base constructor function
...
}
Manager.prototype = new Employee(); //Create prototype chain
Manager.prototype.constructor = Manager;

创建原型链的另一种方法是使用Object.create

Manager.prototype = Object.create(Employee.prototype); //Create prototype chain

这是Object.create在内部实现的方式:

function create(proto) {
  function F() {};      
  F.prototype = proto ;
  return new F();      
}

那么我们何时应该使用Object.createnew Employee()来创建原型链?

Object.create没有任何构造逻辑来创建对象,而我们可以在Employee内部构建逻辑,如this.default = "default"。在这种情况下,使用new Employee()Object.create没有太大区别。但如果我们需要完全避免构造逻辑,我们可以使用Object.create

答案 1 :(得分:1)

你可以试试这个:

Function.prototype.inherit = function(Parent) {
    this.prototype = Object.create(Parent.prototype)
    this.prototype.constructor = this
}

Source(保加利亚郎)

您还可以看到this演示

答案 2 :(得分:1)

如前所述;最好不要创建Parent的实例来设置Child的原型。要重新使用Parent构造函数,您可以在Child中执行Parent.call(this,args);

我喜欢使用参数对象以获得更好的可读性,当在链中调用一堆函数时,函数可以取出并改变与它们相关的部分。例如

function Employee(args) {
  //name is mandatory
  if(typeof args.name === "undefined")
    throw new Error("Cannot create an Employee instance without passing a name.");
  this.name = args.name;
  //age is optional and default is 25
  this.age = (typeof args.age === "undefined")? 25:args,age;
  //optional, defaults to 2500
  this.salary = (typeof args.salary === "undefined")?2500:args.salary;
}

function Manager(args) {
  //re use Employee constructor
  Employee.call(this,args);
  //set Employee specific values same as Employee
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;

var m = new Manager({name:"Harry",age:33,salary:5000});

有关构造函数和原型here的更多信息。

答案 3 :(得分:0)

经理也是一名员工,所以你为什么不这样做:

function Staff(name, age, salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}

function Position(positionName, management_school_name) {
   this.positionName = positionName;
   this.managent_school_name = management_shool_name;
}

Staff.prototype.position = new Position();

答案 4 :(得分:0)

在您想要实现的上述帖子 WHAT 中已正确解释。但AFAIK下面的行将解释为什么就是这样。

有两种方法可以向类中添加公共属性和方法(而不是函数类):

添加公共属性的方法1,添加到每个实例:

function MyClass(){
      this.publicProperty = 'public property'; 
}

添加公共属性的方法2,添加到原型,对所有实例都是通用的:

MyClass.prototype.publicMethod = function(){
      console.log('public method');
}

如果要从Class继承,则需要继承所有公共属性和方法。

继承使用方法1添加的属性和方法:

function MyDerivedClass(){
      MyClass.apply(this);
}

继承使用方法2添加的属性和方法:

MyDerivedClass.prototype = Object.create(MyClass.prototype);

希望这有帮助。