JS: Прототипы
Теория: Абстрактное синтаксическое дерево
В прошлом уроке мы сделали DSL, из которого сразу рендерили HTML. Решение рабочее, но внутри кода много проверок: где атрибуты, где текст, где дети, какая короткая форма была передана.
На маленьком примере это терпимо. На реальном коде такой формат начинает мешать.

В чем проблема прямого рендера
Исходный DSL удобен для человека. Его можно коротко записывать, опускать пустые части и быстро читать.
Но для программы это не лучший формат:
- много условных веток при обработке
- сложнее анализировать структуру
- сложнее делать обратное преобразование
html -> data - внутренний код смешивает две задачи: нормализацию и рендер
Из-за этого следующий логичный шаг - ввести промежуточное представление.
Что такое AST
AST (абстрактное синтаксическое дерево) - это дерево, которое парсер строит из исходных данных перед дальнейшей обработкой.
Идея простая: сначала переводим вход в строгую, единообразную структуру. Потом работаем уже с ней.
Простейшая аналогия из выражений:
- исходник:
x + y - z - внутри: дерево операций и операндов
Дерево уже само хранит структуру и приоритеты, поэтому дополнительная логика для "догадок" почти не нужна.
Почему это полезно в JavaScript и в нашем проекте
JavaScript-движки делают то же самое: сначала парсят исходный код в AST, потом выполняют.
Для нашего HTML Builder польза такая же:
- можно отделить этап парсинга от этапа рендера
- проще добавлять новые внешние синтаксисы DSL
- проще писать анализаторы и преобразования
- внутреннее представление становится стабильным
Новое API урока
Теперь у нас две отдельные функции:
parse() отвечает за нормализацию входа и построение AST.
render() отвечает только за генерацию HTML из уже нормального дерева.
Как выглядит узел AST
Узел в этом уроке сводится к четырем полям:
nameattributesbodychildren
Пример структуры:
Такое дерево проще обходить, проверять и модифицировать. Здесь уже нет неоднозначности, какая позиция за что отвечает.
Итоги
Главная мысль: AST это не "лишняя абстракция", а способ упростить систему.
Когда данные сложные, почти всегда выгодно сделать два шага:
- привести вход к строгой внутренней модели
- работать только с этой моделью
Именно это мы и сделали: отделили парсинг от рендера и получили более предсказуемую архитектуру.

