Вы, наверное, много слышали о терминах прототипическое наследование и классическое наследование. Но что они означают на самом деле?
Прежде чем копаться в этих определениях наследования, вам нужно понять, что такое прототипы и классы в 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, и любые новые массивы, которые вы создаете, могут получить доступ к этому полю. Это одна из важных концепций прототипического наследования.
Итак, в чем основное различие между прототипическим наследованием и классическим наследованием?
Прототипное наследование позволяет любым объектам наследовать методы и поля любых других объектов, тогда как классическое наследование поддерживает только наследование между объектами класса.
Вот и все! Теперь вы понимаете основы каждого прототипа и разницу между ними.