Почему не наследуется конструктор?

129
23 октября 2019, 12:20

Есть 2 функции конструкторов, прототип 1-ой функции-конструктора наследуется через Object.create, но в качестве прототипа ошибочно указан не объект(прототип), а сама функция конструктор. Т.е это ошибка при наследовании прототипа. Но почему из-за этого не работает наследование конструктора во 2 функции-конструктора ?

Пример кода:

function Name(name) { 
  this.name = name; 
} 
 
Name.prototype.sayName = function() { 
  console.log(this.name) 
} 
 
function FullName(name, surname) { 
  Name.call(this, name); //2 - but why didn't work this ? 
  this.surname = surname; 
} 
 
FullName.prototype = Object.create(Name); //1 - mistake 
 
FullName.prototype.sayFullName = function() { 
  console.log(this.name + ' ' + this.surname); 
} 
 
var person = new FullName('Boris', 'Akunin'); 
 
console.log('person', person)

В объекте person будет только свойство surname. В строке 1 была допущена ошибка, но она же, вроде, никак не влияет на наследование конструктора. Т.е в строке 2 идет обычный вызов функции.

Answer 1

Как ни странно, именно ошибка в строке (1) сломала вызов родительского конструктора. :)

Тонкость тут в том, что экземпляры класса Function (т. е. все функции, включая конструкторы) имеют свойство name, причём оно неперезаписываемое:

Object.getOwnPropertyDescriptor(function(){}, 'name')
/* возвращает 
   {value: "", writable: false, enumerable: false, configurable: true}
 */

А неперезаписываемое свойство при наследование блокирует своё изменение даже на объектах-потомках, подробнее об этом можно прочитать на MDN.

Таким образом, экземпляр класса FullName наследуется от экземпляра класса Function, который уже имеет неперезаписываемое name и конструктор Name изменить его не может.

Есть два решения — исправить уже указанную ошибку:

FullName.prototype = Object.create(Name.prototype);

либо просто переименовать свойство name. :)

READ ALSO
Расширить EventTarget, без синтаксиса “class”

Расширить EventTarget, без синтаксиса “class”

Как я могу записать аналог class MyClass extends EventTarget{}, без использования синтаксиса "class"? В спецификации сказано что это только синтаксический сахар,...

125
Как добавить/удалить класс в куки?

Как добавить/удалить класс в куки?

Пожалуйста, подскажите, как можно при: добавлении, удаление классов (при toggleClass например) сохранять результат после перезагрузки страницыЯ...

128
Вывести массив коротким образом в String

Вывести массив коротким образом в String

Есть массив,числа это типа номера маршруток на данном улицеЧисла идут только на возрастание и по порядку

114
Сортировка базы данных по нажитию на кнопки

Сортировка базы данных по нажитию на кнопки

У меня вот есть база данных в формате json

122