Наследование JavaScript: когда мои производные участники? - PullRequest
6 голосов
/ 30 января 2012

Взгляните на следующий код:

function Primate() {
    this.prototype = Object;
    this.prototype.hairy = true;
}

function Human() {
    this.prototype = Primate;
}

new Human();

Когда вы проверяете new Human(), hairy участника нет. Я ожидаю, что будет один. Есть ли другой способ наследования от Primate? Что-то, связанное с Object.create() (ECMAScript5 подходит для моего сценария)?

1 Ответ

4 голосов
/ 30 января 2012

Когда ваш код написан, объекты, созданные с использованием new Human(), будут иметь свойство с именем prototype, значение которого является ссылкой на функцию Primate. Это явно не то, что вы хотите (и это не особенно особенное).

Несколько вещей:

  • Обычно вы хотите изменить prototype функции , которая предназначена для использования в качестве конструктора (с оператором new). Другими словами, вы хотите установить prototype на Human (не на экземпляр из Human).

  • Значение, которое вы присваиваете prototype, должно быть экземпляром требуемого типа (или, если не требуется работа по инициализации, требуемого типа prototype), а не ссылкой его конструктору.

  • Нет необходимости явно присваивать Object (или Object экземпляры) функции prototype. Это неявно.

Вы, вероятно, хотите что-то похожее на это:

function Primate() {
    this.hairy = true; 
}

function Human() {}
Human.prototype = new Primate();
Human.prototype.constructor = Human;

var h = new Human(); 

Human, на который ссылается h, имеет свойство с именем hairy, значение которого равно true.

В предыдущем примере hairy присваивается его значение только после вызова Primate, поэтому Human.prototype должен быть присвоен экземпляр Primate. Вместо этого это можно записать так, чтобы такая инициализация не требовалась

Пример: * 1 052 *

function Primate() {}
Primate.prototype.hairy = true;

function Human() {}
Human.prototype = Primate.prototype;
Human.prototype.constructor = Human;

var h = new Human();
...