Почему `.prototype` и` .__ proto__` разные вещи? - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь понять наследование прототипа 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, насколько я знаю.)

...