我目前正在尝试使用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的角度来看,我提出的一些问题可能是非敏感的,请随意挑战我的预设必要时。
答案 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这样的转录器会重写它。