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

Когда нужно использовать window вместо модулей?

2.0 Middle🔥 171 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

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

Когда нужно использовать window вместо модулей?

Вопрос о использовании window объекта vs модулей — это вопрос о правильной архитектуре кода. В современной разработке (ES6+) правильный ответ простой: почти никогда не используй window для хранения переменных, используй модули. Window должен использоваться только для доступа к браузерным APIs, которые глобальны по природе.

Когда ДЕЙСТВИТЕЛЬНО нужен window

Существует короткий список случаев, когда window легитимно необходим:

1. Доступ к браузерным глобальным API

// Работа с URL
window.location.href = '/dashboard';
console.log(window.location.pathname);

// History API
window.history.back();
window.history.replaceState(state, title, url);

// LocalStorage и SessionStorage
window.localStorage.setItem('user', JSON.stringify(user));
const savedUser = JSON.parse(window.localStorage.getItem('user'));

// DevicePixelRatio для высокодпи экранов
const dpr = window.devicePixelRatio;

// Viewport размеры
const width = window.innerWidth;
const height = window.innerHeight;

2. Media Queries и Responsive Design

// Отслеживание изменения размера
window.addEventListener('resize', () => {
  console.log('Размер экрана изменился');
});

// Media queries из JavaScript
const mediaQuery = window.matchMedia('(max-width: 768px)');
if (mediaQuery.matches) {
  console.log('Mobile device');
}

// Отслеживание изменений media query
mediaQuery.addEventListener('change', (e) => {
  if (e.matches) {
    console.log('Перешли на мобильную версию');
  }
});

3. Работа с открытием новых окон

// Открыть новый tab
window.open('https://example.com', '_blank');

// Работа с фреймами
window.parent.postMessage({ type: 'EVENT' }, '*');
window.top.location.reload();

4. Глобальные обработчики ошибок

// Обработчик необработанных ошибок
window.addEventListener('error', (event) => {
  console.error('Uncaught error:', event.error);
  logErrorToServer(event.error);
});

// Обработчик необработанных Promise rejections
window.addEventListener('unhandledrejection', (event) => {
  console.error('Unhandled promise rejection:', event.reason);
  logErrorToServer(event.reason);
});

Когда НЕ нужен window

Неправильно: использование window для переменных

// ПЛОХО! Загрязняет глобальное пространство имён
window.appConfig = {
  apiUrl: 'https://api.example.com',
  debug: true,
  timeout: 5000
};

window.currentUser = null;
window.isAuthenticated = false;

// Почему это плохо?
// 1. Глобальные переменные сложнее отслеживать
// 2. Конфликты имён в больших проектах
// 3. Сложнее тестировать
// 4. Сложнее рефакторить
// 5. Сложнее понять зависимости между модулями

Правильно: использование модулей

// config.js
export const config = {
  apiUrl: 'https://api.example.com',
  debug: true,
  timeout: 5000
};

// user.js
export let currentUser = null;
export let isAuthenticated = false;

export function setUser(user) {
  currentUser = user;
  isAuthenticated = true;
}

// main.js
import { config } from './config.js';
import { setUser, currentUser } from './user.js';

console.log(config.apiUrl);  // Правильно!
setUser({ name: 'John' });
console.log(currentUser);  // { name: 'John' }

Сравнение подходов

// Сценарий 1: Хранение конфигурации

// ПЛОХО
window.API_URL = 'https://api.example.com';
window.API_TIMEOUT = 5000;

// ХОРОШО
// config.ts
export const API_CONFIG = {
  url: 'https://api.example.com',
  timeout: 5000
} as const;

// ===================================

// Сценарий 2: Глобальное состояние

// ПЛОХО (jQuery/старый подход)
window.store = {
  user: null,
  token: null,
  setUser: function(user) {
    this.user = user;
  }
};

// ХОРОШО (React Context / Zustand)
import { create } from 'zustand';

const useAuthStore = create((set) => ({
  user: null,
  token: null,
  setUser: (user) => set({ user })
}));

// ===================================

// Сценарий 3: Утилиты

// ПЛОХО
window.utils = {
  formatDate: (date) => { /* ... */ },
  parseJSON: (json) => { /* ... */ }
};

// ХОРОШО
// utils/date.ts
export function formatDate(date: Date): string {
  // ...
}

// utils/json.ts
export function parseJSON<T>(json: string): T {
  // ...
}

Когда window используется с легитимной причиной (Legacy код)

Иногда в legacy проектах нужно работать с глобальными переменными:

// Если нужно совместить старый код с новым
(function() {
  // Экспортировать что-то в window для legacy скриптов
  if (typeof window !== 'undefined') {
    window.__APP__ = {
      config: APP_CONFIG,
      utils: APP_UTILS
    };
  }
})();

// Или для работы с Chrome DevTools
if (process.env.NODE_ENV === 'development') {
  window.__REDUX_DEVTOOLS_EXTENSION__ = reduxDevtoolsExtension;
}

Модули vs window: быстрое сравнение

ПараметрWindowМодули
Область видимостиГлобальнаяЛокальная
ТестируемостьПлохаяОтличная
Управление зависимостямиНеявноеЯвное
Конфликты имёнВероятныМаловероятны
ПроизводительностьХорошаяХорошая
ЧитаемостьНизкаяВысокая
Переиспользование кодаСложноПросто
RefactoringОпасноБезопасно

Лучшие практики

// 1. Используй модули для всего приватного
import { config } from './config';
import { api } from './api';

// 2. Window только для браузерных API
window.addEventListener('resize', handleResize);

// 3. Если нужно глобальное состояние, используй state management
import { useAppStore } from './store';

// 4. Для debug информации в dev режиме
if (process.env.NODE_ENV === 'development') {
  window.__DEBUG__ = {
    state: store.getState(),
    dispatch: store.dispatch
  };
}

// 5. Никогда не полагайся на window для критичных данных
// ПЛОХО
if (window.isAdmin) {
  // Это можно обойти через Console
}

// ХОРОШО
if (user.role === 'admin') {
  // Проверка на сервере
}

Вывод

В современной разработке (2024+) с модульной архитектурой (ES6 modules, bundlers, frameworks) window должен использоваться только для доступа к браузерным глобальным API (localStorage, location, innerWidth и т.д.). Для хранения переменных, конфигурации и состояния используй модули и frameworks (React Context, Zustand, Redux и т.д.). Это делает код более тестируемым, поддерживаемым и безопасным.

Когда нужно использовать window вместо модулей? | PrepBro