В настоящее время я пытаюсь создать наследование классов с использованием прототипов в 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 с именем? В С# (язык, который мне больше всего нравится), вы просто вызываете базовый конструктор и передаете необходимые параметры, но не похоже, что в javascript есть эквивалентный шаблон.
Для справки, это то, как это могло бы выглядеть в С#:
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, не стесняйтесь оспаривать мои предпосылки по мере необходимости.
Стандарт ES5 и ниже
В конкретном случае вашего примера ответ headmax делает то, что вам нужно. Однако то, что вы пытаетесь сделать в общем смысле (т.е. Классическое наследование), возможно с С# и другими языками с классическими моделями наследования, но это невозможно в модели прототипа 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, должна быть реализована как сквозная, т.е. вызовите соответствующую функцию во внутреннем объекте Person. По общему признанию, это далеко не фактическое наследование, но оно может аппроксимировать поведение ради вещей, таких как полиморфизм.
РЕДАКТИРОВАТЬ
Ну, это то, о чем я забыл раньше, но на самом деле вы можете добиться большего количества наследования с помощью 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 и любых других функций, которые вы определяете внутри Employee, вам нужно будет изменить видимость видимости области от var name =...
до this.name =...
так что он видится в объеме объекта, который строится (к чему this
относится), в отличие от привязки к сфере действия функции конструктора. Для прекрасных примеров всего этого в использовании см. Здесь.
ES6
С принятием ECMAScript 2015 вы можете теперь обернуть определения классов в синтаксическом сахаре, который намного больше похож на классическое наследование. Но вы должны помнить, что это все еще реализовано с прототипическим наследованием под капотом, поэтому вероятно, что что-то вроде композиции или call()
/apply()
происходит, когда механизм JavaScript фактически выполняет код или транспилер, как Babel, переписывает его.
JavaScript имеет реальные классы с ES6. Они не будут работать в старых браузерах (например, Internet Explorer), но вы можете записать это как
class Person {
constructor(name){
this.name = name;
}
}
class Employee extends Person {
constructor(name, company) {
super(name);
this.company = company;
}
}