Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Объекты JS: Программирование, управляемое данными

Динамическая диспетчеризация – очень мощный механизм, который лёг в основу подхода называемым объектно-ориентированное программирование. Изначально само понятие ООП имело совершенно другой смысл и идеи человека, который придумал ООП, совершенно не похожи на то, что под этим подразумевают сегодня. Его зовут Алан Кэй, обязательно прочитайте о нём. Поэтому когда мы говорим про ООП, мы в первую очередь будем подразумевать современное представление и понимание, и в голове мы у себя будем держать и вспоминать о том, что на самом деле существует несколько пониманий этого слова и они зависят от того, в каком контексте мы об этом говорим.

Объект

В объектном программировании мы оперируем не структурами данных, которые спрятаны за какие-то абстракции, а объектами. Объект – это такая умная структура данных, которая помимо того, что работает просто как некое состояние, с которым можно что-то делать и как-то манипулировать, но он ещё определяет то, какие операции над ним применяются.

Рассмотрим этот код:

const card = percentCard.make('percent card', 60)
card('getName'); // percent card
card('damage', 10); // 6

Способ работы с сущностью card называется передача сообщений. Мы это делали когда работали с парами. Наши пары, а так же card – это самый настоящий объект, который внутри себя содержит какое-то состояние.

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

Функция, которая будет работать, выбирается в зависимости от переданного сообщения и диспетчеризация внутри идёт по имени. То есть объект сам отвечает за то, какой код будет выполняться в случае вызова того или иного метода (в данном случае в зависимости от переданного сообщения).

Реализация

Реализация простая и повторяет полностью то, что было с парами. Если хотите узнать больше про пары, то попробуйте наш курс JS: Составные данные

export const make = (name, percent) =>
  (message, health) => {
    switch (message) {
      case 'getName':
        return name;
      case 'damage':
        return Math.round(health * (percent / 100));
      default:
        return 'undefined method';
    }
  };

Внутри определяется новая функция, которая возвращается наружу. Она принимает на вход message, по которому делается свич и в зависимости от того, что происходит делает ту или иную задачу. Функция содержит какое-то состояние, но в данном случае оно неизменяемо (хотя это может быть не так).

Я надеюсь, что к текущем моменту вы уже поняли, что ООП и функциональное программирование – это вещи разных порядков. Их нельзя сравнивать, потому что функциональное программирование противопоставляется императивному программированию, то есть изменяемое состояние или неизменяемое состояние. В свою очередь ООП про диспетчеризацию, про возможность выбирать реализацию и это прекрасно существует в функциональных языках при функциональном подходе, поэтому эти концепции целиком и полностью дополняют друг друга. Так уж сложилось, что чаще всего объектно-ориентированные языки сами по себе являются императивными. Но при этом, как видите, на JS мы спокойно пишем функциональный код и в будущем мы будем писать его ещё больше.

Характеристика ООП

Бенджамин Пирс – известный учёный, который занимается теорией типов написал следующую вещь в своей книге, которая называется Types and Programming Languages, знаменитая книга о типах в языках программирования:

Вероятно самая фундаментальная характеристика объектно-ориентированного стиля – это то, что когда по отношению к объекту применяется некоторая операция, объект сам определяет, какой код её осуществляет.

Небольшое замечание. То что объект сам определяет, какой код её осуществляет – это то, как оно выглядит снаружи, как мы видим это и какая семантика у этой всей истории, но в реальности с точки зрения имплементации это определяет не объект и это может быть сделано гораздо хитрее, как мы себе не можем это представить. Это очень сильно зависит от конкретной имплементации конкретного языка и его особенностей.

Передача сообщений

С точки зрения Алана Кэя, который придумал ООП, передача сообщений является ключевым фактором и вообще ключевой идеей в ООП. При этом некоторые современные объектно-ориентированные языки взяли всё таки эту идею немножко в себя и используют. В JS, кстати, передача сообщений не используется, но мы её самостоятельно реализовали и теперь, как минимум вы знаете про это. Например, у таких языков как Ruby или PHP есть такая возможность, но она немножко ограничена. С одной стороны там передача сообщений, с другой стороны есть методы и получился такой микс между двумя способами работы.

В нашем случае объект, который мы создали и с которым до сих пор работали, действительно работает с помощью передачи сообщений.

const card = percentCard.make('percent card', 60)
card('getName');
card('damage', 10); // 6

В чём отличие от вызова функции?

Во-первых гораздо более гибкая обработка. Если не существует какой-то функции, то ваш код однозначно будет падать с ошибкой и вы ничего не сможете с этим сделать, только если вы снаружи не обработаете ошибку. Но когда идёт передача сообщений, обработка может идти внутри и сам объект может достаточно хитро реагировать на различные сообщения. Более того, могут интересно использоваться техники когда имя сообщения внутри себя содержит определённые параметры, то есть строится определённым способом. Это позволяет нам распарсив его, то есть извлекая из него определённые куски, понять, что нам нужно.

Классный пример – getName.

card('getName');

Предположим, что у нашего объекта был бы не только getName, но и getSurname, getLastname и много других параметров. Так вот вместо того, чтобы определять множество различных сообщений, которые делают одно и тоже – просто извлекают разные куски нашего внутреннего состояния, мы могли бы внутри определить такой обработчик, который проверял бы, что переданное сообщение начинается с get и после этого идёт какое-то название. Затем он бы его разбирал и использовал это название для того, чтобы определить, а что собственно вернуть и тогда мы бы очень сильно сократили код. Это очень крутая возможность. Например, она активно используется в Ruby и в частности в рельсах.

Ну и второе – это адаптация в работающем коде. Это означает, что объект со временем может менять своё поведение: как он отвечает на сообщение, на какие сообщения он отвечает. Использование сообщений открывает достаточно широкие возможности . Если говорить конкретно про JS, то есть одна хорошая новость, что ES6 (последний стандарт, который сейчас применён и используется) внутри себя несёт так называемые прокси объекты, которые фактически могут имитировать передачу сообщений, что открывает путь к большому количеству возможностей. И судя по тому, что я наблюдаю сейчас в сети люди действительно начинают ими пользоваться и осознавать, что с помощью такого подхода можно строить гораздо более гибкие приложения и делать фишки, которые до этого момента были недоступны.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»