В JavaScript каждый объект является одновременно экземпляром и классом. Для наследования вы можете использовать любой экземпляр объекта в качестве прототипа.
В Python, C ++ и т. Д. Существуют классы и экземпляры как отдельные понятия. Чтобы выполнить наследование, вы должны использовать базовый класс для создания нового класса, который затем можно использовать для создания производных экземпляров.
Почему JavaScript пошел в этом направлении (ориентация объекта на основе прототипа)? Каковы преимущества (и недостатки) ОО на основе прототипа по сравнению с традиционным ОО на основе классов?
javascript
oop
inheritance
prototype-programming
Стефано Борини
источник
источник
GEB
?Ответы:
Здесь есть около сотни терминологических проблем, в основном построенных вокруг кого-то (не вас), пытающегося сделать свою идею похожей на The Best.
Все объектно-ориентированные языки должны уметь работать с несколькими понятиями:
Теперь, что касается сравнения:
Во-первых, весь вопрос "класса" против "прототипа". Идея изначально возникла в Simula, где с помощью метода на основе классов каждый класс представлял набор объектов, которые разделяли одно и то же пространство состояний (читайте «возможные значения») и одни и те же операции, формируя, таким образом, класс эквивалентности. Если вы посмотрите на Smalltalk, так как вы можете открыть класс и добавить методы, это практически то же самое, что вы можете сделать в Javascript.
Позже ОО-языки хотели использовать статическую проверку типов, поэтому мы получили представление о фиксированном классе, установленном во время компиляции. В открытой версии у вас было больше гибкости; в более новой версии у вас была возможность проверить некоторые виды корректности в компиляторе, которые в противном случае потребовали бы тестирования.
На «классовом» языке это копирование происходит во время компиляции. В языке прототипа операции хранятся в структуре данных прототипа, которая копируется и изменяется во время выполнения. Однако, абстрактно, класс по-прежнему является классом эквивалентности всех объектов, которые используют одно и то же пространство состояний и методы. Когда вы добавляете метод в прототип, вы фактически создаете элемент нового класса эквивалентности.
Теперь, зачем это? прежде всего потому, что он обеспечивает простой, логичный, элегантный механизм во время выполнения. Теперь, чтобы создать новый объект или создать новый класс, вам просто нужно выполнить глубокое копирование, копируя все данные и структуру данных прототипа. Вы получаете наследование и полиморфизм более или менее бесплатно: поиск метода всегда состоит из запроса словаря для реализации метода по имени.
Причина, по которой появился скрипт Javascript / ECMA, заключается в том, что, когда мы начинали с этим 10 лет назад, мы имели дело с гораздо менее мощными компьютерами и гораздо менее сложными браузерами. Выбор метода на основе прототипа означал, что интерпретатор может быть очень простым при сохранении желаемых свойств ориентации объекта.
источник
Сравнение, которое слегка смещено в сторону подхода, основанного на прототипах, можно найти в статье « Самость: сила простоты» . В статье приводятся следующие аргументы в пользу прототипов:
Self , вероятно, является первым языком для реализации прототипов (он также ввел в действие другие интересные технологии, такие как JIT, которая позже попала в JVM), поэтому чтение других статей Self также должно быть поучительным.
источник
point
является экземпляром классаPoint
, который является экземпляром метаклассаstandard-class
, который является экземпляром самого себя, ad finitum.Вы должны проверить большую книгу по JavaScript от Дугласа Крокфорда . Он дает очень хорошее объяснение некоторых дизайнерских решений, принятых создателями JavaScript.
Одним из важных аспектов проектирования JavaScript является его система наследования прототипов. Объекты являются первоклассными гражданами в JavaScript, настолько, что обычные функции также реализуются как объекты (точнее, объект 'Function'). По моему мнению, когда он изначально был разработан для работы внутри браузера, он должен был использоваться для создания множества одноэлементных объектов. В браузере DOM вы найдете это окно, документ и т. Д. Все одноэлементные объекты. Кроме того, JavaScript является свободно типизированным динамическим языком (в отличие от, скажем, Python, который строго типизирован, динамический язык), в результате концепция расширения объекта была реализована с использованием свойства «prototype».
Поэтому я думаю, что есть некоторые плюсы для ОО на основе прототипов, реализованных в JavaScript:
Вот некоторые из минусов прототипа OO:
источник