Дополнительные статьи

Паттерн пространство имен

Последнее обновление: 19.11.2023

Если на веб-страницу подключается множество скриптов, то может возникнуть проблема конфликта имен, если разные скрипты определяют переменные/константы и функции с одним и тем же именем. В ряде языков программирования можно сгруппировать функционал в отдельные блоки - "пространства имен" (как в C#) или пакеты (как в Java). Разные пакеты/пространства имен могут определять переменные и функции с одинаковыми именами, но конфликта имен не будет. Однако в JavaScript не существует ни пакетов, ни пространств имен, но есть возможность эмулировать пространства имен с помощью специальной техники, которую еще называют паттерном "пространство имен".

Идея этого паттерна состоит в том, чтобы объединить связанные переменные/константы/функции в отдельный объект, который служит простым контейнером. Для обращения к переменным и функциям внутри подобного контейнера применяется его имя. И пока такие объекты-контейнеры имеют глобально уникальное имя, такой подход не приводит к каким-либо конфликтам имен. В качестве подобного эффекта это позволяет разгрузить глобальную область видимости, убрав из нее определения глобальных переменных и методов.

Например, рассмотрим следующий код:

// определяем объект-пространство имен
var MathLib = MathLib || {}; 
// определяем переменную внутри пространства имен
MathLib.MAX = 1234; 
// определяем функцию внутри пространства имен
MathLib.sum = function(a, b) {  return a + b;};

console.log(MathLib.sum(4, 5)); // 9
console.log(MathLib.MAX); // 1234
MathLib.MAX = 5678;
console.log(MathLib.MAX); // 5678

Здесь определяется пространство имен в виде объекта MathLib (условно говоря пространство имен MathLib). Обратите внимание на форму определения:

var MathLib = MathLib || {}

Данный паттерн предотвращает перезапись объекта MathLib, если он уже существует. Но при таком определении мы не можем использовать ключевые слова let или const для определения объекта. Поэтому в данном случае объект определяется с помощью var.

Затем в MathLib для демонстрации определяются переменная MAX и функция sum, которые мы можем использовать, применяя имя объекта MathLib.

Можно сразу определить содержимое пространства имен:

var MathLib = MathLib || {
    MAX: 1234,
    sum: function(a, b) {  return a + b;}
};

Таким образом, мы можем определять переменные и функции с одинаковыми именами внутри разных объектов-пространств имен, и у нас не возникнет конфликта имен:

var MathLib = MathLib || {
    sum: function(a, b) {  return a + b;}
};
var OtherMathLib = OtherMathLib || {
    sum: function(nums) {  
        let result = 0;
        for(n of nums) result += n;
        return result;
    }
};
console.log(MathLib.sum(4, 5)); // 9
console.log(OtherMathLib.sum([4, 5, 6])); // 15

В данном случае два объекта-пространства имен определяют функцию с одним и тем же именем sum, но разным функионалом. Но поскольку для доступа к функции применяется имя объекта, конфликта имен не будет.

Подобным образом можно определять вложенные пространства имен:

var Messages = Messages || {
    ru: {
        hello: "Привет",
        bye: "Пока"
    },
    en: {
        hello: "Hello",
        bye: "Good bye"
    },
};
console.log(Messages.ru.hello); // Привет
console.log(Messages.en.hello); // Hello
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850