Я пытаюсь понять наследование прототипа JavaScript / ECMAScript (JS) и не могу понять, почему .prototype
отличается от только для чтения .__proto__
(или .@@prototype
, {{prototype}}
или любой другой реализации)has).
Учитывая следующий свернутый код:
const Animal = function() { this.foo = "animal foo"; };
Animal.prototype.getFoo = function () { return this.foo; }
const Dog = function() { Animal.call(this); this.bar = "dog bar"; }
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
let dog = new Dog();
Вещь, которую я не могу понять (1), почему JS требует скрытого свойства прототипа в первую очередь,и (2) почему это свойство не может быть свободно изменено по желанию?
Почему это не было разработано так?
const Animal = function() { this.foo = "animal foo"; };
Animal.getFoo = function () { return this.foo; }
const Dog = function() { Animal(this); this.bar = "dog bar"; } // or super()
Dog.prototype = Animal;
let dog = new Dog();
// dog.prototype points to Dog and __proto__ does not exist at all.
// dog.getFoo() would work because dog does not have own property
// getFoo so dog.prototype.getFoo() would be tried instead, etc.
и , тогда код можно продолжить
const Mammal = function { this.zoo = "mammal zoo"; };
Mammal.prototype = Animal;
Dog.prototype = Mallal;
// dog (instance) now has inherited property zoo and
// inherits from Dog < Mammal < Animal.
Насколько я могу видеть, современные движки JS уже делают более сложные трюки, чем это, поэтому я не думаю, что это "должная производительность", и такое наследование прототипов было бы намного проще понять. Обратите внимание, что .prototype
используется только для определения наследования, и наследование может быть изменено по желанию, как и любое другое свойство.
Я предполагаю, что мне не хватает некоторых важных деталей - можете ли вы указать мне это?
(Обратите внимание, что этот вопрос касается языкового дизайна . Я понимаю, как .prototype
используется оператором new
, а .__proto__
показывает фактическую ссылку, используемую для наследования / отправки. I 'Я спрашиваю причину разделения свойств, потому что я думаю, что он мог быть разработан только с одним свойством, как описано выше. И я знаю, что __proto__
является устаревшим именем для той же вещи, что и .getPrototypeOf()
, которая может возвращать различного значение от .prototype
, насколько я знаю.)