JS: Введение в ООП
Теория: Прототипы
В этом уроке дается небольшое введение в тему прототипов. Полностью раскрыть её одним уроком невозможно. Не хватит даже целого курса. Прототипы познаются только через практику, перемешанную с теоретической подготовкой. Поэтому не переживайте, если не всё поймёте с первого раза, это нормально.
Прототипы — это механизм, который оказывает основное влияние на то, как работают объекты в JavaScript. Сами они напрямую в коде используются редко (и обычно только в библиотеках), но их знание важно для понимания поведения кода и отладки. Особенно при работе с классами, которые мы изучим дальше по курсу. В этом уроке мы затронем только самые основы. Глубоко разобраться с прототипами поможет наш курс, указанный в дополнительных материалах.
В JavaScript с каждым объектом связан прототип. Прототип – это обычный объект, хранящийся в специальном служебном поле [[prototype]] (к этому полю невозможно обратиться напрямую). Его можно извлечь так:
Для чего нужны прототипы
Представим, что мы обращаемся к свойству объекта, и при этом никакого свойства в этом объекте нет. В таком случае мы получим значение undefined. Обычно это так и работает, но есть одна важная особенность.
Если свойства в объекте нет, то JavaScript смотрит прототип этого объекта. Если в прототипе есть искомое свойство, то его значение возвращается. В итоге мы можем обратиться к свойству, которого нет в объекте, но есть в прототипе. И тогда мы получим из прототипа какое-то значение.
В реальности процесс еще сложнее. Если свойство не найдено в прототипе, то JavaScript смотрит прототип прототипа и так далее. Так он проходит до конца цепочки прототипов, то есть до последнего прототипа — это всегда null. На базе этого механизма реализуется наследование. Эта тема выходит за рамки текущего урока.
Прототипы есть даже у обычных JavaScript-объектов:
Именно по этой причине даже пустые объекты содержат свойства и методы:
Доступ к прототипу можно получить не только из объектов, но и из свойства prototype конструктора, который эти объекты создаёт:
Теперь мы можем ответить на вопрос, откуда берется прототип. Прототип – это объект, находящийся в свойстве prototype функции-конструктора, а не сам конструктор. Проверить работу прототипов достаточно легко, изменив их:
При этом никто не мешает заменить значение свойства getName в конкретном объекте. Это никаким образом не отразится на других объектах, так как они извлекают getName из прототипа:
Создание свойств через прототип – и есть правильный способ создания своих абстракций в JavaScript. Любая новая абстракция, которая нам нужна в коде, должна выглядеть как конструктор и прототип, наполненный нужными свойствами.
Что даёт этот механизм?
Самое простое – расширение ядра языка и библиотек без прямого доступа к исходному коду. Прототипы – невероятно гибкий механизм, который позволяет менять всё что угодно из любого места программы в рантайме, то есть во время работы. Например, мы можем добавить или заменить любые методы в любых объектах самого языка:
Как и любой другой мощный механизм, прототипы опасны. Можно наменять такого, что программирование превратится в ад:
Но если использовать этот механизм с умом, то можно получить очень много хорошего. Например, прототипы активно используются в тестировании, они помогают подменить вызовы нежелательных методов, которые выполняют HTTP-запросы. Другой популярный вариант – полифилы. Это код, который добавляет в старые версии JavaScript возможности из новых версий, но не все, конечно — только те, что появляются в виде свойств и методов.
Теперь вы знаете, почему в документации все имена функций описаны так: Number.prototype.toLocaleString().






