Прототипы и прототипное наследование в javascript

6

Prototype and prototypical inheritance

В JavaScript нету классов, есть только объекты. Как нам имплементировать наследование используя только объекты?

Вот есть у нас объект circle. Мы можем сделать новый объект, давайте назовём его shape и добавить общее поведение или все общие методы в этот объект, например метод computeOptimumLocation() и затем как-то мы можем связать объект circle с объектом shape.

Теперь мы обращаемся к объекту object как к прототипу объекта circle.

По существу, prototype это родитель другого объекта!

Каждый раз когда слышите слово prototype — помните это просто родитель (parent)

И так, каждый объект в JS кроме только одного объекта, имеет prototype или parent и он наследует от него всего свойства и методы.

prototype

Давайте, например, создадим пустой объект

let x = {};

Если мы посмотрим на него в devtools то увидим у него свойство __proto__.

Обратите внимание, что __proto__ считается depricated и не рекомендуется обращаться к нему напрямую

Оно доступны в devtools только для того, чтобы помочь вам в решении проблем.

Если мы развернем __proto__, то увидим prototype или родителя этого объекта (x), который мы только что создали.

object base

Итак, у нас есть объект x в памяти и он связан с другим объектом, который является его прототипом. Давайте назовём этот объект object base (базовый объект). Это неофициальный термин. Каждый объект который мы создаем прямо или косвенно, наследуется от базового объекта. Базовый объект это корень всех объектов в JS и у него нет прототипа или родителя.

Мы можем создать другой объект, например y и у него будет точно такой же прототип, как и у x.

Вот что у нас сейчас в памяти: у нас есть x и y и они оба ссылаются на базовый объект. Итак у нас есть единственный instance (экземпляр) базового объекта в памяти.

object base 2

Вот как мы можем это проверить:

Воспользуемся свойством getPrototypeOf базового объекта и укажем в него объект, чтобы получить его прототип.

Object.getPrototypeOf(x) === Object.getPrototypeOf(y); //true

Может возникнуть вопрос, почему не сравнили как то так:

x.__proto__ === y.__proto__

Ответ прост: это свойство считается deprecated и его не следует использовать в коде, но им можно воспользоваться для отладки в консоли.

Теперь разберемся, как мы можем обратиться, например, к методу toString из объекта x, если объект пустой и не содержит не единого метода.

Итак, как же мы получаем доступ к этому методу?

Когда мы обращаемся к свойству или методу объекта, движок JS сначала смотрит если эта пропертя или метод у самого объекта. Если он не может найти его здесь, то он смотрим его в прототипе этого объекта. Если не находит в прототипе, то смотрит в прототипе прототипа, до тех пор, пока не доберется до корневого объекта, который мы назвали базовым.

Итак это прототипное наследование в действии, когда пытаемся получить свойство или метод объекта, движок js движется по цепочке прототипов чтобы найти цель.

Прототип это просто обычный объект в памяти.

Все объекты имеют прототипы или родителя, кроме корневого объекта.

You might also like More from author

Leave A Reply

Your email address will not be published.