В JavaScript есть ряд разительных отличий от других языков программирования. Одним из них является такая вещь как прототип. Часто можно услышать фразы “прототипное наследование”, так вот я постараюсь объяснить что это, так как тема простая, но новичкам с этим не везёт.
Есть ряд “нормальных” ООП языков, в них есть наследования, инкапсуляция, иногда интерфейсы, иногда абстрактные классы, в жс нет ничего из этого, те кто знают как работает ООП в других язык, могут порадоваться что в жс есть хотябы оператор new и instanceof, и нет ничего вышесказанного (в обычном смысле). Те, кто не знают других ООП языков, имейте ввиду, то, что ниже, редко где кроме жс увидишь, это особенность жс.
Тем не менее, в жс можно особым способом сделать даже множественное наследования, а патерны типа “контракт” делаются, но по-другом.
Объект - экземпляр какого-либо класса, класс - тоже объект. Сразу оговорим, что значит тоже объект: вода это жидкость, но жидкость не вода, точно также класс это объект, но не всякий объект класс. Я считаю, что читатель уже знает, что такое переменная, работал хоть чуточку с объектами и конечно понимает что же такое объект в ЖС и что такое свойство объекта (property).
|
|
Я специально пишу слова Объект с большой буквы, класс курильщика будет написан с маленькой буквы, класс здорового человека с большой. Потом будет ясно почему.
Что такого, что массив принадлежит к классу Массив? А то, что есть ряд “операций”, которые можно проводить именно над массивами, но не над объектами. Есть что-то особенное, что отличает массив от объекта.
|
|
Но и наоборот, у массива есть что-то, что есть у любого объекта, можно сказать, что массив это объект, у которого есть свои фишки.
|
|
hasOwnProperty - помогает нам пролить свет на то, что же внутри этого объекта взялось из прототипа, а что его “родное”. Т.е. внутри объекта есть что-то, оно наследуется от Объекта, и возможно не только (смотря о чём говорим!), а есть то, что пренадлежит только этому конкретному объекту.
Поблагодарив сообщество mdn, я аккуратно позаимствую кусок их примера:
|
|
И так, что же мы натворили в примере выше, мы создали Класс, это же целая Личность! И Мы сделали что-то богохульное, с именем Allah. Пожалуй, менее религиозные и более внимательные обратили внимания, что за громкими словами класс скрывается всем известная функция. Но эта функция пишется с большой буквы! А почему? Да хоть как-то их в коде отличить. Ещё раз: между функцией и классом в жс нет разницы! Ну и моё любимое, между функцией и объектом тоже не много, ведь функция (смотри выше) это же Объект, экземпляр его. Вот такая жс приколюшка, получается, мы создаём объекты оператором new от других объектов, а классов как бы и нет, ну то есть, они есть, но они не классы а функции. И что дальше, может на лету будем методы и свойства классов писать?!
|
|
Повтор. Есть операторы new и instanceof. Есть классы, они же функции. Есть прототип, прототип это объект, в этот объект можно добавить метод или свойство, и это же появится у всех наследников этого класса. Можно определить родное ли свойство с помощью метода hasOwnProperty.
Итог. Самое базовое объяснение что такое прототип дано, прототип это то, что наследуется, что напишешь в прототип, появится и у наследников. Есть ещё множество вещей, которые я не осветил, например дичь и свойство proto, которым рекомендуют не пользоваться. Или как всё же сделать наследование и множественное наследование конечно для тех, кто уважает ес6, в нём это делается короче но под капотом всё тоже самое, основы нужно знать