Вы хотите вместо этого:
function Man(name) {
Human.call(this, name, "Male");
}
Что этот код делает
Похоже, вы только пытаетесь вызвать конструктор родителя, Human
, что не то же самое, это прототипное наследование. Приведенный выше код принимает конструктор для Human
и применяет его к this
- новому объекту Man
.
Что делает ваш код
Линия Man.prototype = new Human(name, "Male")
меняет прототип Man
каждый раз, когда новый Человек создан. Кроме того, вы завершаете повторное назначение объекта прототипа и поэтому применимы только к созданным объектам после это назначение, то есть не первое. Следовательно, m.name
не определено.
Правильного прототипичное наследование
Обратите внимание, что вызов конструктора родителя, так как в моем коде выше, не причин Man
автоматически наследуют методы, назначенные Human.prototype
. Лучший способ сделать это - клонировать Human.prototype
в Man.prototype
, но за пределами любых конструкторов. Как это:
function Man(name) {
Human.call(this, name, "Male");
}
function inherit(parent, child) {
if (Object.create) child.prototype = Object.create(parent.prototype);
else {
for (var key in parent.prototype) {
if (!parent.prototype.hasOwnProperty(key)) continue;
child.prototype[key] = parent.prototype[key];
}
}
}
inherit(Human, Man);
Это может показаться довольно многословным, и альтернативой может быть сделать это:
Man.prototype = new Human('no name', 'Male');
Какой будет работать, но вызывает нежелательные побочные эффекты, так как мы вынуждены присвойте имя dud prototype
, и это позволяет конструктору для Human
вызвать дополнительное время только для назначения прототипа. Будьте осторожны, если вы спуститесь по этому пути, а затем измените конструктор Human
, чтобы сделать больше, чем просто присвоить свойства this
.
Должны ли быть определены методы как в базе, так и в sub? Не могли бы вы показать мне полный пример базового классического наследования с использованием JavaScript [пожалуйста]? – Sam