Декларативность JavaScript в БЭМ-проекте проявляется в следующем:
В БЭМ-методологии к JavaScript применяются основные принципы объектно-ориентированного программирования (ООП).
В БЭМ JavaScript-реализация одного блока отделена от другого. Каждый блок предоставляет API для взаимодействия с другими блоками.
Декларация блока позволяет скрыть его внутреннюю реализацию. Так как элементы всегда являются внутренней реализацией блока, обращение к ним возможно только через API самого блока.
Декларативное описание поведения блоков позволяет использовать методы базового блока внутри производного, наследовать их. Новый блок может получать все свойства и методы базового.
Также можно создавать цепочки наследования — блок наследуется от другого, который, в свою очередь, наследуется от третьего и т.д.
Примеры реализации доступны в документации к i-bem.js.
Блокам с JavaScript-реализацией могут соответствовать узлы в HTML. В этом случае говорится о том, что блоки имеют DOM-представление.
В простейшем случае блок соответствует DOM-узлу один к одному. Однако DOM-узел и блок — это не всегда одно и то же. Можно разместить несколько блоков на одном DOM-узле (это называется микс), а также реализовать один блок на нескольких DOM-узлах.
Существуют блоки без DOM-представления. В JavaScript они представлены в виде объектов, имеющих свои методы.
Примеры реализации доступны в документации к i-bem.js.
БЭМ-методология предполагает работу с независимыми блоками. Однако на практике полная независимость блоков недостижима.
Блоки могут взаимодействовать друг с другом с помощью:
Примеры реализации доступны в документации к i-bem.js.
БЭМ-методология рекомендует выстраивать взаимодействие между блоками в иерархическом порядке в соответствии с их расположением в DOM-дереве. Вложенный блок не должен ничего знать о родительском блоке, так как это нарушает принцип независимости компонентов.
Элемент — это внутренняя реализация блока. В БЭМ-методологии принято реализовывать дополнительные хелперы блока для работы с его элементами. Обращение напрямую к элементу другого блока невозможно. Взаимодействие с элементом происходит только только через API блока, которому принадлежит данный элемент.