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

Предположим, программист написал функцию с названием inArray(). Через некоторое время потребовалось подключить библиотеку стороннего разработчика, в которой все функции объявлены в глобальной области видимости. Если в этой библиотеке объявлена функция с названием inArray(), то возникнет конфликт имен. Следует заметить, что никакого сообщения об ошибке в данном случае выведено не будет. Функция, которая объявлена последней, просто переопределит уже существующую функцию. Далее все зависит от частоты использования функции. Все инструкции, которые зависят от этой функции, станут работать некорректно. В итоге будет получен результат, который не планировался, или программа завершится с критической ошибкой.

Чтобы избежать подобной ситуации, следует строго придерживаться концепции пространств имен. Согласно этой концепции модуль может импортировать в глобальную область видимости только один идентификатор. Следует заметить, что это требование касается не только модулей сторонних разработчиков, но и относится к вашим собственным программам.

В языке JavaScript в качестве пространства имен используются объекты. Созданный экземпляр помещается в глобальную область видимости, а остальные идентификаторы доступны через свойства объекта:

let myModule = {}; // Объявление пространства имен
myModule.test = function() {
   console.log('Это функция test');
}
myModule.inArray = function() {
   console.log('Это функция inArray');
}
myModule.test();
myModule.inArray();

В этом примере функция inArray() расположена внутри пространства myModule. Поэтому конфликт имен сводится к минимуму. Однако может возникнуть ситуация, когда пространства имен называются одинаково. В этом случае решением является создание вложенных объектов. Очень часто название пространства имен совпадает с названием сайта разработчика. В качестве основного объекта используется название зоны, а вложенный объект носит название домена. Например, для сайта http://example.com/ создание пространства имен будет выглядеть так:

var com; // Объявляем, иначе будет ошибка при проверке
if (!com) com = {}; // Объявление пространства имен
else if (typeof com != 'object')
   throw new Error('Идентификатор com не является объектом');
if (com.example)
   throw new Error('Пространство имен уже занято');
com.example = { // Объявление вложенного пространства имен
   test: function() {
      console.log('Это функция test');
   },
   inArray: function() {
      console.log('Это функция inArray');
   }
};
com.example.test();
com.example.inArray();

Таким образом, если домен принадлежит вам, никакого конфликта имен не будет, но пользоваться таким длинным названием не очень удобно. Учитывая, что присваивание объектов производится по ссылке, а не по значению, то данная проблема решается просто. В программе определяется короткий идентификатор и в нем сохраняется ссылка на объект:

let $ = com.example;
$.test();
$.inArray();

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

(function($) {
   $.test();
   $.inArray();
})(com.example);

В этом примере идентификатор $ будет доступен только внутри анонимной функции, а так как функция не имеет названия, в глобальной области видимости никакой идентификатор не сохраняется.

Учебник по Node.js и JavaScript
Учебник по JavaScript (Node.js) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов