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

Что можно использовать вместо window?

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

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

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

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

Отличный вопрос! Он затрагивает фундаментальное понимание окружения выполнения JavaScript и различий между браузерным и серверным (или изолированным) JavaScript. window — это глобальный объект только в среде браузера. В зависимости от контекста, вместо него можно использовать несколько других объектов или подходов.

Вот основные альтернативы, сгруппированные по среде выполнения:

1. В браузере (но для изоляции или модульности)

Даже в браузере прямое обращение к глобальному window считается антипаттерном в современной модульной разработке, так как "загрязняет" глобальную область видимости и усложняет тестирование.

globalThis (Стандарт ES2020)

Это современный, универсальный способ доступа к глобальному объекту в любой среде выполнения (браузер, Node.js, Web Workers и т.д.).

// В браузере:
console.log(globalThis === window); // true

// В Node.js:
console.log(globalThis === global); // true

// Универсальный код для доступа к глобальному объекту
const globalObject = globalThis;

// Установка/получение глобальной перемены
globalObject.MY_APP_CONFIG = { apiUrl: '...' };

Преимущество: Код становится более переносимым и предсказуемым.

Обращение через замыкание (паттерн "Dependency Injection")

Вместо прямого доступа к window из любой точки кода, лучше получать зависимости явно.

// Плохо (прямая зависимость)
function playAudio(url) {
  const audio = new window.Audio(url);
  audio.play();
}

// Хорошо (зависимость инжектирована)
function createAudioPlayer(globalObj) {
  return function playAudio(url) {
    const audio = new globalObj.Audio(url);
    audio.play();
  };
}

const playAudio = createAudioPlayer(window); // Здесь явно передаём window
// Теперь функцию легко протестировать с мок-объектом!

2. В Node.js (серверный JavaScript)

В Node.js нет объекта window, так как нет браузерного окружения. Основные глобальные объекты:

global

Это исторический аналог window в Node.js, но его использование для пользовательских глобальных переменных также не рекомендуется.

// В Node.js
console.log(global === globalThis); // true

// Но глобальные переменные объявляются и без явного указания на global
myVar = 42; // Не рекомендуется! Автоматически попадает в global
console.log(global.myVar); // 42

process

Уникальный для Node.js объект, содержащий информацию о текущем процессе и методы для взаимодействия с ним. Аналогов в браузере нет.

// Доступ к аргументам командной строки
console.log(process.argv);

// Работа с переменными окружения
const apiKey = process.env.API_KEY;

// Управление процессом
process.exit(0);

3. В Web Workers (отдельные потоки браузера)

Воркеры выполняются в изолированном контексте без доступа к window, DOM и некоторым API.

self

В Web Workers (DedicatedWorker, SharedWorker, ServiceWorker) глобальным объектом является self. globalThis также ссылается на него.

// внутри файла worker.js
self.addEventListener('message', (event) => {
  const data = event.data;
  // Выполняем тяжелые вычисления
  const result = data * 2;
  // Отправляем результат обратно
  self.postMessage(result);
});

// globalThis также работает
console.log(globalThis === self); // true в воркере

4. В изолированных средах (iframe, sandbox)

При работе с <iframe> каждый фрейм имеет свой собственный глобальный объект.

window для iframe (но другой!)

Для доступа к window другого фрейма нужно получить ссылку на его элемент.

// Родительский фрейм обращается к дочернему
const iframeEl = document.getElementById('myFrame');
const iframeWindow = iframeEl.contentWindow;

// Дочерний фрейм обращается к родительскому
const parentWindow = window.parent;
const topWindow = window.top; // Корневое окно

5. Рекомендации и лучшие практики

  1. Используйте globalThis для универсального кода, который потенциально может выполняться в разных средах (например, библиотеки).
  2. Избегайте создания глобальных переменных. Вместо этого:
    *   Используйте модули (ES Modules, CommonJS).
    *   Создавайте пространства имен (namespace) в виде одного глобального объекта для вашего приложения.
    *   Применяйте паттерны Dependency Injection или контейнеры состояний (Redux, MobX, Context API в React).

```javascript
// Пример модуля (ES Module)
// config.js
export const API_URL = 'https://api.example.com';

// app.js
import { API_URL } from './config.js';
// Никакого обращения к window для конфигурации!
```

3. Проверяйте наличие API перед использованием, особенно если код кроссплатформенный.

```javascript
// Универсальная проверка на поддержку Fetch API
if (typeof globalThis.fetch === 'function') {
  // Безопасно используем fetch
} else {
  // Полифилл или fallback-логика
}
```

4. Для тестирования всегда мокайте глобальные объекты. Прямой доступ к window или global делает модули неудобными для юнит-тестов.

Итог

Выбор объекта вместо window строго зависит от контекста выполнения:

  • Универсальный портативный доступ: globalThis (ES2020+)
  • Браузер, основной контекст: window (но предпочтительнее globalThis)
  • Node.js: global, process, но по факту — globalThis
  • Web Workers: self или globalThis
  • Лучшая архитектура: Избегайте прямого использования глобальных объектов через паттерны модульности и явной передачи зависимостей.

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