2013-12-22 4 views
2

Скажем, у меня есть Employee класс:Как наследовать свойства базового класса и вызвать конструктор базового класса вызова в javascript?

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 инкапсулирует name, age и salary.

Итак, как мне нужно иметь дело с повторяющимися параметрами?

ответ

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.create и new Employee() создать цепочку прототипов?

Object.create не имеет каких-либо строительных логики для создания объекта в то время как мы могли бы иметь строительную логику внутри Employee, как this.default = "default". В этом случае использование new Employee() мало чем отличается от Object.create. Но если нам нужно, чтобы избежать строительства логики полностью, мы могли бы использовать Object.create

+0

Это как это делается в целом? Или мой базовый дизайн плохой? – batman

+0

+1 Но что, если мне нужны данные и в прототипе? – thefourtheye

+0

@learner: это повторное использование вашей логики для инициализации «имя», «возраст», «зарплата» –

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(); 
+0

не могли бы вы объяснить? Я действительно не понимаю. – batman

+0

В моем примере я объединяю ваш класс Manager и Employee в один класс Staff. Теперь Manager и Employee также являются сотрудниками, поэтому они используют одну и ту же информацию: имя, возраст, зарплату. Если вы хотите сделать Staff как Manager, просто установите его прототип позиции. Извините за мой английский! – HICURIN

1

Вы можете попробовать это:

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

Source (болгарский Lang)

Вы можете увидеть также this демо

1

Как указано выше; лучше не создавать экземпляр родителя для установки прототипа Child. Чтобы повторно использовать конструктор родителя, вы можете сделать Parent.call(this,args); в Child.

Мне нравится использовать объект аргументов для лучшей читаемости и когда в цепочке вызывается куча функций, функции могут выносить и мутировать часть, которая их касается. Например

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.

+0

Спасибо. Является ли это примером прототипа или псевдоклассического наследования? – batman

+0

@learner думаю. Это был единственный способ сделать это в течение длительного времени. В последнее время существует другой способ сделать это с Object.create, но вы должны добавить функцию init или constructor для инициализации конкретных экземпляров экземпляра, чтобы в принципе это сводилось к одному и тому же. – HMR

+0

прототипные и псевдоклассические на самом деле совершенно разные. – batman

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); 

Надежда это помогает.

Смежные вопросы