使用父构造函数参数的Javascript继承

时间:2017-10-19 18:10:56

标签: javascript inheritance constructor prototype

我目前正在尝试使用javascript中的原型创建类继承,我理解它在下面的简单示例中是如何工作的。

var Person = function(){
    var name = "Steve";
}

var Employee = function(){
    var company = "Stack Overflow";
}

Employee.prototype = new Person;

var employee1 = new Employee();

但现在假设我想在构造函数中添加参数,以便在创建对象时设置值。所以更新后的代码如下所示:

var Person = function(initName){
    var name = initName;
}

var Employee = function(initName, initCompany){
    //How can I use initName to set the value in the prototype class?

    var company = initCompany;
}

Employee.prototype = new Person;

var employee1 = new Employee("Bob", "Intel");

如何使用名称调用Person构造函数?在C#(我最熟悉的语言)中,您只需调用基本构造函数,并传递必要的参数,但似乎javascript中没有等效的模式。

作为参考,这可能是C#中的样子:

public class Person
{
    string name;

    public Person(string initName)
    {
        name = initName;
    }
}

public class Employee : Person
{
    string company;

    public Employee(string initName, string initCompany) : base(initName)
    {
        company = initCompany;
    }
}

var employee1 = new Employee("Bob", "Intel");

免责声明:正如您所看到的,我主要是一个面向对象的程序员,但我目前正在使用javascript工作,因此从javascript的角度来看,我提出的一些问题可能是非敏感的,请随意挑战我的预设必要时。

2 个答案:

答案 0 :(得分:2)

从ES6开始,JavaScript都有真正的类。他们不能在旧浏览器(即Internet Explorer)中工作,但您可以将其写为

class Person {
  constructor(name){
    this.name = name;
  }
}

class Employee extends Person {
  constructor(name, company) {
    super(name);
    this.company = company;
  }
}

答案 1 :(得分:1)

标准ES5及以下

对于您示例的具体情况,headmax's answer可以满足您的需求。但是,您可以使用C#和其他使用经典继承模型的语言在一般意义上(即经典继承)尝试做的事情,但它与JavaScript原型不一样。模型。您可能最接近使用合成,例如:

var Person = function(initName){
    var name = initName;
}

var Employee = function(initName, initCompany){
    var innerPerson = new Person(initName);

    var company = initCompany;
}

var employee1 = new Employee("Bob", "Intel");

然后,您希望在Employee类上实现镜像或扩展Person类的任何附加功能都必须实现为passthrough,即。在内部Person对象中调用相应的函数。不可否认,这远非实际的继承,但它可以为多态性等事物近似行为。

修改

这是我以前完全忘记的事情,但您实际上可以使用call()apply()实现更多的继承行为。使用call或apply允许您在指定的上下文中运行函数(包括对象构造函数),这样您就可以在子上下文中运行父构造函数,如下所示:

var Person = function(initName){
    var name = initName;
}

var Employee = function(initName, initCompany){
    Person.call(this, initName);
    var innerPerson = new Person(initName);

    var company = initCompany;
}

var employee1 = new Employee("Bob", "Intel");

但是,如果您希望能够访问Employee构造函数中的name属性以及您在Employee中定义的任何其他函数,则需要从var name = ...更改名称的范围可见性到this.name = ...,以便它在被构造的对象的范围内可见(这是this引用的),而不是绑定到构造函数的范围。有关所有这些内容的很好示例,请参阅here

<强> ES6

随着ECMAScript 2015的采用,您现在可以将您的类定义包装在语法糖中,这看起来更像是经典继承。但是你必须记住,这仍然是在原型继承下实现的,因此当JavaScript引擎实际执行代码时,可能会出现类似于组合或call() / apply()的内容。像Babel这样的转录器会重写它。