← Назад к вопросам

Лежит ли шина событий только в window

2.0 Middle🔥 122 комментариев
#Soft Skills и рабочие процессы

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Лежит ли шина событий только в window?

Нет, шина событий (Event Bus или система событий) НЕ лежит только в объекте window. Это распространённое заблуждение. Правильнее сказать, что в браузерах глобальная область видимости и точка входа для многих нативных событий действительно связана с window, но сама концепция шины событий гораздо шире и реализуется на разных уровнях.

Различие между нативной системой событий браузера и паттерном «Шина событий»

  1. Нативная система событий DOM (в браузере):
    *   **Корневым объектом** для большинства событий, связанных с DOM, BOM (Browser Object Model) и загрузкой страницы, действительно является объект **`window`**. Это потому, что `window` представляет глобальный контекст выполнения в браузере.
    *   События, такие как `click`, `load`, `resize`, `keydown`, всплывают (bubble) по дереву DOM, но их целью (target) может быть любой элемент. Объект события доступен через `window.event` (устаревшее) или передается в функцию-обработчик.
    *   **Пример работы с событиями через `window`:**
    ```javascript
    // Слушатель можно добавить непосредственно на window
    window.addEventListener('resize', () => {
        console.log('Размер окна изменился');
    });

    // Глобальное событие, связанное с загрузкой страницы
    window.onload = function() {
        console.log('Страница полностью загружена');
    };

    // Событие клика на документе также доступно через window
    window.addEventListener('click', (event) => {
        console.log('Клик по координатам:', event.clientX, event.clientY);
    });
    ```

2. Паттерн «Шина событий» (Event Bus / Event Emitter):

    *   Это **архитектурный паттерн**, а не нативная конструкция. Он используется для организации взаимодействия между компонентами, которые не должны знать друг о друге напрямую (слабое связывание).
    *   Его можно реализовать в любом контексте: Node.js, Vue.js, React (с помощью сторонних библиотек), в vanilla JavaScript.
    *   **Он не привязан к `window`**. В Node.js, например, нет объекта `window`, но есть собственный модуль `events`, который предоставляет класс `EventEmitter` — классическую реализацию шины событий.
    *   **Простая реализация шины событий на чистом JavaScript:**
    ```javascript
    class EventBus {
        constructor() {
            this.listeners = {};
        }

        on(event, callback) {
            if (!this.listeners[event]) {
                this.listeners[event] = [];
            }
            this.listeners[event].push(callback);
        }

        off(event, callback) {
            if (!this.listeners[event]) return;
            this.listeners[event] = this.listeners[event].filter(
                listener => listener !== callback
            );
        }

        emit(event, data) {
            if (!this.listeners[event]) return;
            this.listeners[event].forEach(listener => {
                listener(data);
            });
        }
    }

    // Создаем экземпляр шины. Он НЕ привязан к window.
    const globalEventBus = new EventBus();

    // Использование в разных частях приложения
    globalEventBus.on('userLoggedIn', (userData) => {
        console.log('Панель пользователя обновлена:', userData.name);
    });

    globalEventBus.emit('userLoggedIn', { name: 'Анна', id: 42 });
    ```

Где ещё «живут» шины событий или их аналоги?

  • В Node.js: Ядро системы — модуль events (require('events')).
  • Во фреймворках:
    *   **Vue 2:** `Vue.prototype.$bus` (хотя сейчас это считается антипаттерном, на смену пришли Vuex/Pinia) или отдельные библиотеки.
    *   **Vue 3:** Рекомендуется использовать библиотеки (`mitt`, `tiny-emitter`) или Provide/Inject для глобальных событий.
    *   **React:** Нет встроенной шины, но используются контекст (Context API), сторонние библиотеки (`EventEmitter3`, `mitt`), или стейт-менеджеры (Redux, MobX, который активно использует observable-события).
  • В нативном JavaScript: Любой объект может стать «шиной», если реализует методы подписки и публикации, как в примере выше.

Вывод

Объект window в браузере служит глобальной целью для системных и DOM-событий, но он не является единственной или универсальной «шиной событий» в разработке. Шина событий — это паттерн, который можно реализовать где угодно для декаплинга кода. Использовать глобальный объект window как event bus для логики приложения — плохая практика, так как это приводит к загрязнению глобальной области видимости, конфликтам имен и сложности отладки. Для коммуникации между компонентами приложения следует создавать выделенные экземпляры шин или использовать инструменты, предоставляемые фреймворком.