Namespace Pattern

Namespace Pattern — паттерн организации кода, при котором весь публичный API библиотеки или модуля группируется под одним глобальным объектом-пространством имён, предотвращая коллизии имён в глобальной области видимости.

Зачем нужно

До появления ES-модулей и CommonJS любой скрипт загрязнял глобальный window. Namespace Pattern решал эту проблему, создавая одно имя в глобальной области и группируя под ним весь API. Сегодня актуален в браузерном коде без сборщиков, в jQuery-плагинах и legacy-проектах.

Где используется

  • Библиотеки без ES-модулей (jQuery $, Lodash _, Moment moment)
  • Legacy-код, где несколько команд добавляют скрипты напрямую
  • Браузерные расширения (глобальный объект расширения)
  • CDN-версии библиотек для использования через <script>

Основной контент

Базовый Namespace

// Плохо: всё в глобальной области
var userName = 'Иван';
function getUser() {}
function saveUser() {}

// Хорошо: один глобальный объект
var MyApp = MyApp || {}; // создаём или используем существующий

MyApp.userName = 'Иван';
MyApp.getUser = function {};
MyApp.saveUser = function {};

Вложенные пространства имён

var MyApp = MyApp || {};
MyApp.utils = MyApp.utils || {};
MyApp.ui = MyApp.ui || {};
MyApp.api = MyApp.api || {};

// Вспомогательная функция для создания пространства имён
function namespace(obj, path) {
  const parts = path.split('.');
  let current = obj;
  parts.forEach(part => {
    current[part] = current[part] || {};
    current = current[part];
  });
  return current;
}

namespace(MyApp, 'ui.components.modal');
MyApp.ui.components.modal.open() = function {
  console.log('Modal открыт');
};

MyApp.ui.components.modal.open();

IIFE + Namespace (Module Pattern без раскрытия)

var MyApp = MyApp || {};

MyApp.cart = (function {
  // Приватные переменные
  let items = ;

  // Приватные функции
  function calculateTotal() {
    return items.reduce((sum, item) => sum + item.price, 0);
  }

  // Публичный API
  return {
    add(item) { items.push(item); },
    remove(id) { items = items.filter(i => i.id !== id); },
    total { return calculateTotal; },
    count { return items.length; }
  };
});

MyApp.cart.add({ id: 1, name: 'Книга', price: 500 });
console.log(MyApp.cart.total); // 500

Современная альтернатива: ES-модули

// utils.js
export const formatDate = (d) => d.toLocaleDateString('ru-RU');
export const clamp = (n, min, max) => Math.min(Math.max(n, min), max);

// main.js
import * as Utils from './utils.js';
console.log(Utils.formatDate(new Date));
// ES-модули — современный namespace без глобального загрязнения

Частые ошибки

  • Перезапись существующего объекта — без MyApp = MyApp || {} повторное подключение скрипта обнуляет всё. Всегда используйте оператор ||.
  • Глубокое вложение без утилиты — ручное создание a.b.c.d вызывает Cannot read properties of undefined. Используйте вспомогательную функцию namespace.
  • Применение в проектах со сборщиком — если есть webpack/vite, используйте ES-модули, не Namespace Pattern. Namespace — решение для окружений без систем модулей.

Связанные темы

Ресурсы