Reputation: 561
I am currently trying to create class inheritance using prototypes in javascript, and I understand how that works in the simple example below.
var Person = function(){
var name = "Steve";
}
var Employee = function(){
var company = "Stack Overflow";
}
Employee.prototype = new Person;
var employee1 = new Employee();
But now assume that I want to add parameters to the constructors so that I can set the values as I create the objects. So the updated code would look like this:
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");
How can I call into the Person constructor with the name? In C# (the language I'm most comfortable with), you would simply call the base constructor, and pass through the necessary parameters, but it doesn't seem like there is an equivalent pattern in javascript.
For reference, this is what it might look like in 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");
Disclaimer: As you can see, I am primarily a object oriented programmer, but I am currently working in javascript, so some of what I've asked may be non-sensical from a javascript perspective, feel free to challenge my presuppositions as necessary.
Upvotes: 1
Views: 2791
Reputation: 1252
Standard ES5 and below
For the specific case of your example, headmax's answer does what you need. However, what you're trying to do in a general sense (that is, classical inheritance) may be possible with C# and other languages with classical inheritance models, but it's not possible the same way with the JavaScript Prototype model. You can probably get closest to that using composition, like so:
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");
Then, any addition functionality you would want to implement on the Employee class that mirrors or extends the Person class would have to be implemented as a passthrough, ie. call the corresponding function in the inner Person object. Admittedly, this is far from actual inheritance, but it can approximate the behavior for the sake of things like polymorphism.
EDIT
Well this is something I completely forgot about before, but you can actually achieve a bit more of inheritance behavior using call() or apply(). Using call or apply allows you to run a function (including object constructors) in a specified context, so you can run the parent's constructor in the context of the child, like this:
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");
However, if you wanted to be able to access the name property inside the Employee constructor and any other functions you define inside Employee, you'd need to change name's scope visibility from var name = ...
to this.name = ...
so that it is visible in the scope of the object being constructed (which is what this
refers to) as opposed to being bound to the scope of the constructor function. For great examples of all of this in use, see here.
ES6
With the adoption of ECMAScript 2015, you can now wrap your class definitions in syntactic sugar that looks a lot more like classical inheritance. But you have to remember that this is still implemented with prototypical inheritance under the hood, so likely there's something like composition or call()
/apply()
going on when the JavaScript engine actually executes the code or a transpiler like Babel rewrites it.
Upvotes: 1
Reputation: 763
JavaScript has real classes as of ES6. They won't work in older browsers (i.e. Internet Explorer), but you can write this as
class Person {
constructor(name){
this.name = name;
}
}
class Employee extends Person {
constructor(name, company) {
super(name);
this.company = company;
}
}
Upvotes: 3