Почему я не могу получить доступ к свойству родительского класса из экземпляра дочернего класса в наследовании JS?

#javascript #prototypal-inheritance

#javascript #прототипное наследование

Вопрос:

У меня есть два класса. Я хочу получить доступ type к свойству родительского класса из экземпляра:

 // Parent class
function Animal() { this.type = 'animal' }

// Child class
function Rabbit(name) { this.name = name }

// I inherit from Animal
Rabbit.prototype = Object.create(Animal.prototype);
Rabbit.prototype.constructor = Rabbit; // I want to keep Rabbit constructor too

// I instantiate my Rabbit and am trying to access rabbit.type
const rabbit = new Rabbit('Bunny');
rabbit.name // => Bunny
rabbit.type // => undefined. WHY?
  

Я знаю, как это решить и получить доступ type , но…

 // all is the same

// Child class
function Rabbit(name) {
  Animal.apply(this, arguments); // Just need to add this line in Rabbit class
  this.name = name 
}

// all is the same

rabbit.name // => Bunny
rabbit.type // => animal
  

… но почему это не работает в первом примере? Возможно ли достичь этого без использования Animal.apply ?

Комментарии:

1. «Возможно ли достичь этого без использования Animal.apply — вы должны вызвать конструктор базового класса в конструкторе производного класса. Так работает ООП. В противном случае, кто будет инициализировать rabbit.type ?

Ответ №1:

Да, если вы добавите type в прототип:

   Animal.prototype.type = "animal";
  

Или вы могли бы скрыть Animal.apply вызов за class сахаром:

  class Animal {
   constructor() {
      this.type = "animal";
   }
 }

 class Rabbit {
   constructor(name) {
     super(); // <<<
     this.name = name;
   }
 }
  

Ответ №2:

Rabbit.prototype = Object.create(Animal.prototype); расширяет только свойства, определенные в prototype цепочке. Свойства, определенные в конструкторе, не будут расширены.

Попробуйте это,

 ...    
Rabbit.prototype = new Animal();
...
  

Обновленный пример:

 // Parent class
function Animal() { this.type = 'animal' }

// Child class
function Rabbit(name) { this.name = name }

Rabbit.prototype = new Animal();
Rabbit.prototype.constructor = Rabbit;

const rabbit = new Rabbit('Bunny');
console.log(rabbit.name);
console.log(rabbit.type);