JS прототип: Наследование - PullRequest
0 голосов
/ 13 октября 2018

Из данной статьи MDN

enter image description here

Почему мы не можем просто сделать следующий код вместо указанногона картинке, есть ли разница между ними?

Teacher = Object.create(Person);

Ответы [ 4 ]

0 голосов
/ 13 октября 2018

Когда вы создаете новый экземпляр с вашим конструктором, например,

  const teacher = new Teacher();

, JS делает следующее под капотом:

1) Создает новый объект, который наследует конструкторы prototype property

2) Вызывает конструктор с this новым объектом:

 const teacher = Object.create(Teacher.prototype); // 1
 Teacher.call(teacher); // 2

Теперь, если вы хотите, чтобы учитель унаследовал все методы и свойства Person, у вас естьTeacher.prototype наследовать Person.prototype, поскольку экземпляры наследуют это.Итак, это:

  teacher  -> Teacher.prototype
  teacher2 ->

должно быть изменено на

 teacher  -> Teacher.prototype -> Person.prototype
 teacher2 ->

, поэтому прототип учителя должен наследовать прототип лиц.

 Teacher.prototype = Object.create(Person.prototype);

Другая строка однако:

  Teacher = Object.create(Person);

Не имеет особого смысла, поскольку это разрушает конструктор Учителя, поскольку Object.create возвращает объект, а не функцию.Однако вы можете:

 Object.setPrototypeOf(Teacher, /*to*/ Person);

Тогда Teacher унаследует все статические свойства Person, но экземпляры не будут наследовать ничего, так как Teacher.prototype не наследует Person.prototype.

0 голосов
/ 13 октября 2018
Teacher = Object.create(Person);

с помощью приведенной выше строки кода вы присваиваете учителю совершенно другое значение.

Вместо этого вы могли бы задать вопрос о следующем:

Teacher.prototype = Person.prototype

, нов этом случае также проблема в том, что любое изменение в прототипе Учителя также изменит прототип Person (поскольку они ссылаются на один и тот же объект), и это может иметь нежелательные побочные эффекты.

Итак,

Teacher.prototype = Object.create(Person.prototype);

правильно

0 голосов
/ 13 октября 2018

У вашего вопроса есть два подвопроса.

1) Назначение Teacher.prototype против Teacher:

let Teacher = function() { /* does something */ } // <-- the constructor

Teacher.prototype = Object.create(Person.prototype); // <-- the constructor did NOT lost 
Teacher = Object.create(Person.prototype); // <-- the constructor lost 

В более низкой версии вы потеряете конструктор из Teacher (конечно, если он существует).А в верхнем вы перезапишете только его прототип.

2) Назначение Person.prototype против Person:

Teacher.prototype = Object.create(Person); // Normally `Person` does not have any properties
Teacher.prototype = Object.create(Person.prototype); // But `Person.prototype` does.

Другими словами, можно очень хорошо добавить свойства Person, а не Prototype, но обычно свойства добавляются вPerson.prototype, чтобы они могли наследоваться экземплярами Person.

Person.foo = function() {}
const person = new Person()
person.foo // undefined

// vs
Person.prototype.foo = function() {}
const person = new Person()
person.foo // its a function
0 голосов
/ 13 октября 2018

Object.create создает объект, который не может быть вызван.Даже если вы передадите функцию (конструктор) в качестве аргумента, объект, создаваемый Object.create, не будет иметь внутреннего свойства [[Call]], что делает объекты функций вызываемыми.Он не наследуется через цепочку прототипов.

Итак, вкратце, вам нужно определить Teacher как конструктор (или использовать синтаксис class, который по-прежнему делает его функцией конструктора), чтото, что вы не можете сделать с Object.create.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...