Логика прототипов в Javascript
В популярном учебнике learn.javascript.ru в уроке о прототипах есть один хороший пример:
let animal = {
eats: true
};
function Rabbit(name) {
this.name = name;
}
Rabbit.prototype = animal;
И казалось бы все нормально, есть Животное и Кролик который наследует от него свойства через Rabbit.prototype, прослеживается логичная иерархия. Свойства же самого Кролика у нас создаются с помощью конструктора Rabbit.
Но почему в встроенных конструкторах используется немного другая логика, менее очевидная.
Например при создании const arr = new Array() свои свойства и методы специфичные для массива мы получаем из Array.prototype, а не из самого Array. По аналогии с кроликом, из Array.prototype мы должны получить свойства и методы иерархией выше, т.е свойства объектов.
Понимаю что в данном случае это нужно чтобы "скрыть" встроенные свойства, и отделить от тех которые добавляем мы. Но пока я все еще в замешательстве...
Ответы (1 шт):
В примере скорее всего хотели продемонстрировать, что "так работает".
По аналогии с кроликом, из Array.prototype мы должны получить свойства и методы иерархией выше, т.е свойства объектов
А где в этом примере "иерархией выше"? animal - просто объект, который прямо записывается в прототип кролика.
Когда из объекта вызывается метод:
- JS cперва проверит наличие этого метода среди свойств объекта. Если его там нет,
- Будет искать метод в
.prototypeфункции-конструктора, с помощью которого был создан этот объект. Соответственно, у созданного объекта есть внутреннее свойство.__proto__которое ссылается на.prototypeсвоего конструктора. Не путать __proto__ и prototype: Первое - внутри созданных объектов, второе - свойство функции-конструктора. - Если и здесь его не будет...
.prototype- сам является объектом, у которого тоже может быть.__proto__- попробует поискать там, и т.д.
Касаемо Array.prototype...
let arr = ["a", "b", "c"];
console.log( arr.hasOwnProperty("0") ); // true
console.log( arr.hasOwnProperty("4") ); // false
Что же произошло?
Хотим вызвать метод hasOwnProperty()
Есть ли внутри
arrтакой? Нет, там только свойства"0", "1", "2"которые соответственно хранят значения"a", "b", "c"(и свойствоlength: 3)Идет к
arr.__proto__оно же,Array.prototype
let arr = ["a", "b", "c"];
console.log( arr.__proto__ === Array.prototype ); // true;
Можно вызвать console.log( Array.prototype ) и убедиться, что там тоже нет метода hasOwnProperty()
Но есть .__proto__ который тоже ссылается на некий объект
let arr = ["a", "b", "c"];
console.log( arr.__proto__ === Array.prototype)
console.log( Array.prototype.__proto__ === Object.prototype) // true
console.log( arr.__proto__.__proto__ === Object.prototype ) // true
И о чудо, находится hasOwnProperty(), который в итоге вызывается в контексте arr.
Это можно представить в виде здания. Ищу метод:
- Проверил у себя - не нашел,
- Зашел на первый этаж (моя функция-конструктор), открыл дверь (
prototype), не нашел метод в комнате, - Через лестницу (
__proto__) поднялся на следующий этаж. Открыл дверь там (prototypeконструктора, от которого наследуем), и т.п. - Если дошел до крыши, так ничего и не нашел - выдам ошибку
... is not a function


