> Как реализовать функцию шаблонизатора строки с подстановкой параметров в JavaScript? (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
Функция шаблонизатора принимает строку с плейсхолдерами вида {{key}} и объект параметров, заменяя плейсхолдеры на соответствующие значения. Реализуется через String.prototype.replace с регулярным выражением и колбэком, либо через split/map. Важно учитывать экранирование, вложенные пути, отсутствующие ключи и производительность при частых вызовах.
Подробное объяснение
Шаблонизатор - это функция, которая заменяет в строке плейсхолдеры на значения из переданного объекта. Базовая реализация использует регулярное выражение для поиска плейсхолдеров и колбэк для подстановки.
Ключевые аспекты:
- Формат плейсхолдеров: обычно
{{key}},{key}или%key% - Обработка отсутствующих ключей: возвращать пустую строку, исходный плейсхолдер или бросать ошибку
- Вложенные пути: поддержка
{{user.name}}через lodash.get или рекурсивный обход - Экранирование: возможность вывести
{{literal}}без подстановки - Производительность: кеширование скомпилированных шаблонов при повторных вызовах
Продвинутые реализации могут поддерживать:
- Условные блоки (
{{#if condition}}...{{/if}}) - Циклы (
{{#each items}}...{{/each}}) - Фильтры и трансформации значений
- Частичную компиляцию (precompile)
На практике
В реальных проектах редко пишут шаблонизатор с нуля - используют готовые решения (Handlebars, Mustache, Lodash template). Однако понимание внутреннего устройства важно для:
- Отладки и оптимизации существующих шаблонов
- Написания кастомных утилит для специфических форматов (например, генерация SQL или конфигов)
- Реализации простых интерполяций без лишних зависимостей
Типичный сценарий - форматирование сообщений в UI: t('Hello, {{name}}!', { name: 'John' }).
Пример кода
JAVASCRIPTfunction simpleTemplate(str, params) {return str.replace(/\{\{(.+?)\}\}/g, (match, key) => {const trimmed = key.trim();return params[trimmed] !== undefined ? params[trimmed] : match;});}// С поддержкой вложенных ключейfunction deepTemplate(str, params) {const getValue = (obj, path) => {return path.split('.').reduce((acc, part) =>acc && acc[part] !== undefined ? acc[part] : undefined, obj);};return str.replace(/\{\{(.+?)\}\}/g, (match, key) => {const value = getValue(params, key.trim());return value !== undefined ? value : match;});}// С кешированиемconst templateCache = new Map();function cachedTemplate(str, params) {if (!templateCache.has(str)) {templateCache.set(str, new Function('params','return `' + str.replace(/\{\{(.+?)\}\}/g, '${params["$1"]}') + '`'));}return templateCache.get(str)(params);}
Как отвечать на собеседовании
Начни с простого решения через replace, затем добавь обработку edge cases. Покажи понимание trade-off между простотой и производительностью. Упомяни, что в production используешь готовые библиотеки, но знаешь, как работает под капотом. Если спросят про безопасность - объясни, почему eval/new Function опасны и как их избежать.
Что проверяет интервьюер
- Владение регулярными выражениями и методами строк
- Понимание работы замыканий и кеширования
- Умение проектировать API (какие параметры принимать, что возвращать)
- Навыки обработки ошибок и краевых случаев
- Знание, когда стоит использовать готовое решение, а когда писать своё
Типичные ошибки
- Использование
evalилиnew Functionбез экранирования (XSS-уязвимость) - Игнорирование пробелов внутри плейсхолдеров (
{{ name }}vs{{name}}) - Мутация исходного объекта параметров
- Отсутствие обработки циклических ссылок в объекте
- Неправильная обработка специальных символов в значениях (например,
$в replace) - Создание нового RegExp при каждом вызове вместо кеширования
> Похожие задачи по frontend
Какие методы для работы с контекстом this существуют и в чем их различия (bind, call, apply)
Как работать с датами в JavaScript и использовать ли библиотеки
Как сделать так, чтобы функция в Map могла быть удалена сборщиком мусора в JavaScript
Почему garbage collector не очищает переменную в случае замыкания в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью