# Особенности реализации JavaScript по БЭМ-методологии

* [Декларативный стиль](#Декларативный-стиль)
* [Принципы ООП в JavaScript по БЭМ](#Принципы-ООП-в-javascript-по-БЭМ)
* [Представление динамических блоков в DOM](#Представление-динамических-блоков-в-dom)
* [Взаимодействие блоков](#Взаимодействие-блоков)
* [Взаимодействие блока с его элементами](#Взаимодействие-блока-с-его-элементами)

## Декларативный стиль

Декларативность JavaScript в БЭМ-проекте проявляется в следующем:

* Поведение каждого блока описывается независимо.
* Состояния блока задаются декларативно. При [изменении состояний](#Реакция-на-изменение-модификаторов) автоматически вызывается код, который задекларирован для этого состояния.
* Логика работы блока описывается как набор действий и условий, при которых эти действия необходимо выполнять. Это позволяет разделять функциональность блока на отдельные части и использовать [уровни переопределения](../key-concepts/key-concepts.ru.md#Уровень-переопределения).

> [Подробнее о применении уровней переопределния в JavaScript](#Работа-с-уровнями-переопределения)

## Принципы ООП в JavaScript по БЭМ

В БЭМ-методологии к JavaScript применяются основные принципы объектно-ориентированного программирования (ООП).

### Инкапсуляция

В БЭМ JavaScript-реализация одного блока отделена от другого. Каждый блок предоставляет API для [взаимодействия с другими блоками](#Взаимодействие-блоков).

Декларация блока позволяет скрыть его внутреннюю реализацию. Так как элементы всегда являются внутренней реализацией блока, [обращение к ним](#Взаимодействие-блока-с-его-элементами) возможно только через API самого блока.

### Наследование

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

Также можно создавать цепочки наследования — блок наследуется от другого, который, в свою очередь, наследуется от третьего и т.д.

> Примеры реализации доступны в документации к [i-bem.js](https://ru.bem.info/technology/i-bem/current/i-bem-js-decl/#Наследование-блока).

## Представление динамических блоков в DOM

Блокам с JavaScript-реализацией могут соответствовать узлы в HTML. В этом случае говорится о том, что **блоки имеют DOM-представление**.

В простейшем случае блок соответствует DOM-узлу один к одному. Однако DOM-узел и блок — это не всегда одно и то же. Можно разместить несколько блоков на одном DOM-узле (это называется [микс](../key-concepts/key-concepts.ru.md#Микс)), а также реализовать один блок на нескольких DOM-узлах.

Существуют **блоки без DOM-представления**. В JavaScript они представлены в виде объектов, имеющих свои методы.

> Примеры реализации доступны в документации к [i-bem.js](https://ru.bem.info/technology/i-bem/current/i-bem-js-decl/#Синтаксис-декларации).

## Взаимодействие блоков

БЭМ-методология предполагает работу с независимыми блоками. Однако на практике полная независимость блоков недостижима.

Блоки могут взаимодействовать друг с другом с помощью:

* Подписки на события других экземпляров блоков.
* Подписки на изменения модификаторов.
* Непосредственного вызова методов других экземпляров блоков или статических методов класса другого блока.
* Любых паттернов взаимодействия. Например, канала событий: все коммуникации происходят благодаря сообщениям, которые компоненты публикуют и слушают с помощью посредника.

> Примеры реализации доступны в документации к [i-bem.js](https://ru.bem.info/technology/i-bem/current/i-bem-js-interaction/).

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

## Взаимодействие блока с его элементами

Элемент — это внутренняя реализация блока.
В БЭМ-методологии принято реализовывать дополнительные хелперы блока для работы с его элементами. Обращение напрямую к элементу другого блока невозможно. Взаимодействие с элементом происходит только только через API блока, которому принадлежит данный элемент.
