> Был ли опыт работы с нативным JavaScript и event listeners? (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Cyber Interactive

Стек: JavaScript

> Пример ответа

Короткий ответ

Да, есть обширный опыт работы с нативным JavaScript и event listeners. Работал с addEventListener, removeEventListener, всплытием и перехватом событий, делегированием, кастомными событиями через CustomEvent и EventTarget. Использовал passive listeners для оптимизации скролла, AbortController для отписки, а также разбирался с event loop и микротасками при асинхронной обработке событий.

Подробное объяснение

Event listeners - фундаментальный механизм взаимодействия с DOM в нативном JavaScript. Основные аспекты работы:

  • Фазы события: capture (перехват) → target → bubble (всплытие). Третий аргумент addEventListener (useCapture/options) управляет фазой.
  • Делегирование событий: вешаем один listener на родителя, обрабатываем события от дочерних элементов через event.target. Критично для динамических списков и таблиц.
  • Управление памятью: обязательная отписка от событий при удалении элементов (removeEventListener) для предотвращения утечек. Использую AbortController для групповой отписки.
  • Оптимизация: passive: true для touch/wheel событий, debounce/throttle для resize/scroll, requestAnimationFrame для анимаций.
  • Кастомные события: dispatchEvent + CustomEvent для создания своей событийной модели, что полезно при работе без фреймворков.
  • Event loop: понимание, что синхронные listener'ы блокируют основной поток, а асинхронные операции внутри них ставятся в очередь микротаск.

На практике

В реальных проектах сталкивался с:

  • Проблемой утечек памяти в SPA приложениях без фреймворков - решал через WeakMap для хранения ссылок на listener'ы и автоматическую отписку при unmount.
  • Оптимизацией drag-and-drop: использовал pointer events вместо mouse/touch для унификации, passive: false для preventDefault.
  • Делегированием событий для таблиц с тысячами строк - один listener на tbody вместо N на каждую строку.
  • Кастомными событиями для межмодульной коммуникации в микросервисной архитектуре на чистом JS.
  • AbortController для отмены запросов при уходе со страницы - передавал сигнал в fetch и listener'ы.

Пример кода

JAVASCRIPT
// Делегирование с AbortController
class TableManager {
constructor(tableEl) {
this.controller = new AbortController();
this.tableEl = tableEl;
this.init();
}
init() {
this.tableEl.addEventListener('click', (e) => {
const row = e.target.closest('tr');
if (!row) return;
const id = row.dataset.id;
this.handleRowClick(id);
}, { signal: this.controller.signal });
}
destroy() {
this.controller.abort(); // отписка от всех событий разом
}
}
// Кастомное событие с передачей данных
const event = new CustomEvent('user-action', {
detail: { userId: 123, action: 'save' },
bubbles: true
});
document.dispatchEvent(event);

Как отвечать на собеседовании

Начни с конкретного опыта: "Да, работал с event listeners в production на проектах X и Y". Затем структурируй ответ по ключевым аспектам: управление памятью, оптимизация, делегирование, кастомные события. Подчеркни понимание event loop и влияние listener'ов на производительность. Приведи пример решения реальной проблемы (утечка, производительность). Упомяни современные API (AbortController, passive, pointer events). Не углубляйся в базовые вещи - покажи экспертный уровень.

Что проверяет интервьюер

  • Глубину понимания event propagation (capture/bubble) и умение выбирать фазу под задачу.
  • Знание паттернов управления памятью (отписка, WeakMap, AbortController).
  • Опыт оптимизации производительности (passive, debounce, делегирование).
  • Понимание event loop и асинхронности в контексте событий.
  • Умение работать с кастомными событиями для создания гибкой архитектуры.

Типичные ошибки

  • Забывают отписываться от событий, создавая утечки памяти в SPA.
  • Используют анонимные функции в addEventListener, что делает removeEventListener бесполезным.
  • Не учитывают фазу события - вешают listener на capture по умолчанию, когда нужно bubble.
  • Злоупотребляют делегированием без проверки event.target, что приводит к обработке лишних кликов.
  • Используют preventDefault() без passive: false для touch/wheel, получая предупреждения в консоли.
  • Пытаются синхронно обрабатывать высокочастотные события (scroll/resize) без throttle/debounce.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью