Вы, наверное, много слышали о терминах прототипическое наследование и классическое наследование. Но что они означают на самом деле?

Прежде чем копаться в этих определениях наследования, вам нужно понять, что такое прототипы и классы в javascript.

Прототип — это объект, содержащий список методов и полей, доступных по умолчанию.

Возьмем, к примеру, метод indexOf из строки. Мы никогда не определяли его, но в любое время, когда мы хотим получить доступ к этому методу из любой строки, мы можем это сделать.

Если вы сделаете console.log для строкового прототипа, вот что вы получите:

Итак, теперь мы знаем, что такое прототип. Что же такое наследование прототипов?

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

Например, объект Array наследует список методов и полей, характерных для объекта-прототипа массива. Такие функции, как map, reduce и filter, являются прототипами методов, которые наследуются каждым объектом массива.

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

Теперь поговорим о классах в javascript.

Классы в JavaScript — это функции, добавленные в ES6, которые предназначены для имитации ключевого слова class из других языков. Как правило, в класс включаются следующие функции:

  • конструктор
  • методы

На самом деле классы — это просто синтаксический сахар вокруг прототипного наследования. Идея состоит в том, чтобы классифицировать ряд поведений и полей в одном типе класса.

Вот пример класса и классического наследования в javascript:

Другими словами, классическое наследование — это идея, согласно которой один класс наследует функции и переменные от родительского класса. Обратите внимание, что классическое наследование строго ограничено наследованием между двумя классами.

В приведенном выше примере у нас есть класс человека и класс студента. Класс person содержит переменную имени и функцию, которая выводит ее имя.

Класс студента является дочерним классом класса человека, мастер-класса. Этот студенческий класс не только имеет доступ к своему собственному полю id, но также имеет доступ к полям и методам своего родительского класса (this.getName() и name);

Понятно. Что такое прототипическое наследование?

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

Допустим, вы объявляете const str = «hi» и используете console.log(str._proto_) на странице инструментов разработчика, вы сможете увидеть [constructor: ƒ, concat: ƒ, pop: ƒ, push: ƒ, …].

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

Вы также можете добавлять новые методы-прототипы к любым объектам, например к массиву. Вы можете написать Array.prototype.newMethod = newMethod, и любые новые массивы, которые вы создаете, могут получить доступ к этому полю. Это одна из важных концепций прототипического наследования.

Итак, в чем основное различие между прототипическим наследованием и классическим наследованием?

Прототипное наследование позволяет любым объектам наследовать методы и поля любых других объектов, тогда как классическое наследование поддерживает только наследование между объектами класса.

Вот и все! Теперь вы понимаете основы каждого прототипа и разницу между ними.