Когда я начал изучать JavaScript, я обнаружил, что понимание прототипов и прототипного наследования довольно запутанно и пугающе! Несмотря на то, что вы можете писать код JavaScript, не имея каких-либо знаний о прототипах в JavaScript, необходимо хорошее понимание прототипов, поскольку это поможет вам отладить код или понять, почему определенная часть кода иногда не работает!

Прототипы — один из самых важных столпов JavaScript! В этой статье мы поймем, что такое прототипы, что такое глобальные объекты, что это за свойство __proto__ и как наследование работает в JavaScript под капотом.

Итак, давайте начнем без дальнейших церемоний,

Когда мы создаем функцию в JavaScript, JavaScript Engine создает два объекта:

  1. Сам функциональный объект
  2. Объект-прототип

Например, рассмотрим это,

Допустим, мы создаем функцию f1() следующим образом:

Затем то, что делает JS Engine, он создает два объекта, как указано выше,

Сам объект функции f1 и объект-прототип функции f1,

Что это за прототип, который вы видите внутри этого объекта f1?

Что ж, JS Engine создает свойство в объекте функции, которое указывает на объект-прототип функции.

Мы можем получить доступ к объекту f1 напрямую, сделав это,

Однако, если мы хотим получить доступ к объекту-прототипу f1, мы можем получить к нему доступ, используя это свойство prototype,

Теперь предположим, что мы создаем новый объект из этой функции f1.

и если мы получим к нему доступ, мы увидим, что есть нечто, называемое __proto__

Этот __proto__ является свойством, которое JS Engine создает для каждого объекта! Что ж, это свойство __proto__ указывает на объект-прототип функции (в данном случае оно будет указывать на объект-прототип f1)

Мы можем проверить, указывают ли свойство прототипа f1 и свойство прототипа myobj на один и тот же объект-прототип или нет, сделав это:

как мы видели выше, мы можем получить доступ к объекту-прототипу функции, аналогичным образом мы можем получить доступ к самому объекту f1, используя свойство, называемое конструктором. Конструктор — это свойство объекта-прототипа, которое помогает нам получить доступ к самой функции.

Предположим, если мы хотим узнать, кто создал этот объект «myobj», то нам нужно просто использовать это свойство конструктора, чтобы узнать это,

Таким образом, мы получаем функцию f1!

Мы также можем создать новый объект, используя это свойство конструктора,

Это просто подразумевает создание объекта myobj2 с использованием той же функции/конструктора, которая создала объект myobj.

До сих пор мы видели, что это за свойство прототипа, что такое свойство __proto__ и свойство конструктора, на что они указывают и каково их использование!

Однако очень часто использовать свойство __proto__ не рекомендуется!

Глобальный объект

В JRE точно так же, как у вас есть глобальный объект окна, у вас также есть глобальные функции. И одна из этих глобальных функций называется Object. Имя функции — Object, но тип — function. Но поскольку функции — это Objects в JavaScript, это также считается Object. Я знаю, это звучит немного запутанно!😬

Объект-прототип!

Давайте создадим функционального человека и новый объект p1 из него,

Глядя на объект-прототип человека, мы задаемся вопросом, кто создал объект-прототип этого человека?

Что ж, он был автоматически создан «новым объектом»! Сам объект-прототип человека имеет свойство __proto__, которое указывает на прототип глобального объекта.

Предположим, если мы попытаемся получить доступ к какому-либо свойству объекта p1, JS Engine сначала попытается найти его внутри p1. Если он не найдет его там, он пойдет вверх по цепочке прототипов, используя свойство __proto__ p1.

p1.__прото__

Если он даже не найдет его и там, он снова поднимется на один шаг вверх по цепочке прототипов.

p1.__прото__.__прото__

А если и там не найдет, то вернет undefined!

Теперь есть один вопрос, эта цепочка прототипов никогда не заканчивается? Есть ли у прототипа базового объекта свойство __proto__?

Нет, у него есть свойство __proto__, но оно указывает на null. Давайте проверим это,

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

Наследование в JS полностью отличается от других языков программирования. В отличие от классического наследования.

Предположим, если у нас есть функция Person (как обсуждалось выше). А теперь у нас также есть функция Учитель. Учитель будет иметь все свойства Человека.

Первоначально прототип человека, а также свойство прототипа учителя (__proto__) указывают на базовый прототип объекта.

В этом случае Учитель и человек не связаны между собой. Учитель не будет обладать никакой собственностью Person. Что ж, чтобы преодолеть это, мы можем сделать так, чтобы объект-прототип Учителя (свойство __proto__) указывал на объект-прототип Person.

Теперь учитель может получить доступ ко всем свойствам человека.

Это было все о прототипах и прототипном наследовании!

Надеюсь, эта статья поможет!

Приятного обучения!😀