JS: Прототипы

Теория: Абстрактное синтаксическое дерево

В прошлом уроке мы сделали DSL, из которого сразу рендерили HTML. Решение рабочее, но внутри кода много проверок: где атрибуты, где текст, где дети, какая короткая форма была передана.

На маленьком примере это терпимо. На реальном коде такой формат начинает мешать.

AST

В чем проблема прямого рендера

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

Но для программы это не лучший формат:

  • много условных веток при обработке
  • сложнее анализировать структуру
  • сложнее делать обратное преобразование html -> data
  • внутренний код смешивает две задачи: нормализацию и рендер

Из-за этого следующий логичный шаг - ввести промежуточное представление.

Что такое AST

AST (абстрактное синтаксическое дерево) - это дерево, которое парсер строит из исходных данных перед дальнейшей обработкой.

Идея простая: сначала переводим вход в строгую, единообразную структуру. Потом работаем уже с ней.

Простейшая аналогия из выражений:

  • исходник: x + y - z
  • внутри: дерево операций и операндов

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

Почему это полезно в JavaScript и в нашем проекте

JavaScript-движки делают то же самое: сначала парсят исходный код в AST, потом выполняют.

Для нашего HTML Builder польза такая же:

  • можно отделить этап парсинга от этапа рендера
  • проще добавлять новые внешние синтаксисы DSL
  • проще писать анализаторы и преобразования
  • внутреннее представление становится стабильным

Новое API урока

Теперь у нас две отдельные функции:

import { render, parse } from './solution';

const actual = render(parse(data));

parse() отвечает за нормализацию входа и построение AST. render() отвечает только за генерацию HTML из уже нормального дерева.

Как выглядит узел AST

Узел в этом уроке сводится к четырем полям:

  • name
  • attributes
  • body
  • children

Пример структуры:

{
  name: 'html',
  attributes: {},
  body: '',
  children: [
    {
      name: 'meta',
      attributes: {},
      body: '',
      children: [
        { name: 'title', attributes: {}, body: 'hello, hexlet!', children: [] },
      ],
    },
  ],
}

Такое дерево проще обходить, проверять и модифицировать. Здесь уже нет неоднозначности, какая позиция за что отвечает.

Итоги

Главная мысль: AST это не "лишняя абстракция", а способ упростить систему.

Когда данные сложные, почти всегда выгодно сделать два шага:

  1. привести вход к строгой внутренней модели
  2. работать только с этой моделью

Именно это мы и сделали: отделили парсинг от рендера и получили более предсказуемую архитектуру.

Рекомендуемые программы

Дальше

Завершено

0 / 10

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845