2014-09-12 4 views
3

Мой вопрос просто:Добавление к прототипу экземпляра другого прототипа: JavaScript

Как создать прототип класса, который наследует от прототипа другого класса?

Мой код ниже работает, пока я не попытаюсь позвонить Pierre.mySkill(), после чего консоль говорит, что функция не определена.

Моей причиной для этого, теоретически, является возможность создавать экземпляры Pirault, а также экземпляры Person и быть в состоянии добавить к прототипу Pirault без необходимости добавлять к Person's.

function Person (name, age){ 
    this.name = name; 
    this.age = age; 
} 

Person.prototype.info = function(){ 
    console.log('I am '+this.name+' and I am '+this.age+' years old.'); 
}; 

function Pirault(){ 
    this.skill = arguments[2]; 

    Person.apply(this, arguments); 
} 

Pirault.prototype.mySkill = function(){ 
    console.log('My skill is '+this.skill); 
} 

Pirault.prototype = Object.create(Person.prototype); 
Pirault.prototype.constructor = Pirault; 

var Pierre = new Pirault('Pierre', 30, 'Programming'); 
+1

Так что «умение» - это «Пьер»? – elclanrs

+0

woops! Спасибо, что поймал это, я хотел обновить его до того, как я разместил сообщение. – papiro

+1

Вот упрощенная версия вашей проблемы: 'var foo = {}; foo.name = 'foo'; foo = {}; console.log (foo.name); '. Это должно быть довольно очевидно, почему 'foo.name' возвращает' undefined'. –

ответ

2

Организуйте свой код так, что все методы прототипа определяются после создается объект-прототип. Например:

Pirault.prototype = Object.create(Person.prototype); 
Pirault.prototype.constructor = Pirault; 

Pirault.prototype.mySkill = function(){ 
    console.log('My skill is '+this.skill); 
} 

Demo. Как бы то ни было, вы правильно определяете метод на прототипе, но затем теряете его, когда объект (созданный Object.create) становится новым Pirault.prototype.

2

В качестве альтернативного подхода для этого не нужны конструкторы. Все, что вам нужно в современных браузерах, это объекты и Object.create:

var Person = { 
    info: function() { 
    console.log('I am '+ this.name +'and I am '+ this.age +' years old.') 
    } 
} 

var Pirault = Object.create(Person) 
Pirault.mySkill = function() { 
    console.log('My skill is '+ this.skill) 
} 

var pierre = Object.create(Pirault) 
pierre.name = 'Pierre' 
pierre.age = 30 
pierre.skill = 'Programming' 

pierre.mySkill() //=> My skill is Programming 

console.log(Pirault.isPrototypeOf(pierre)) //=> true 
console.log(Person.isPrototypeOf(pierre)) //=> true 
+0

Этот подход хорошо работает, если все базовые объекты являются «межфазными» (гем), т. Е. Содержат только методы для работы. В противном случае нужно также создать их экземпляр, и, на мой взгляд, это может стать беспорядочным. Тем не менее, хороший подход, +1 от меня.) – raina77ow

+0

ОДНА ТЫСЯЧА СПАСИБО. Если бы я мог выставлять вас не один раз, я бы это сделал. Вы не можете себе представить, сколько статей я прочитал, продвигая подход Class/constructor/new-based, и я всегда чувствовал, что что-то было «не совсем правильно» ... – papiro

+0

На самом деле существует более чем один способ организовать иерархию объектов - например, mixins ('Base.call (this)'). – raina77ow

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