JavaScript. Подробное руководство, 6-е издание, стр. 138
<b> // свойства класса Set или использовать символ подчеркивания в качестве префикса.</b><b> function v2s(val) { /* ... */ }</b><b> function objectld(o) { /* ... */ }</b><b> var nextId = 1;</b><b> // Общедоступным API этого модуля является функция-конструктор Set().</b><b> // Нам необходимо экспортировать эту функцию за пределы частного</b><b> // пространства имен, чтобы ее можно было использовать за ее пределами.</b><b> // В данном случае конструктор экспортируется за счет передачи его</b><b> // в виде возвращаемого значения. Он становится присваиваемым значением</b><b> // в выражении в первой строке выше, return Set;</b><b>}()); // Вызвать функцию сразу после ее объявления.</b>Обратите внимание, что такой прием вызова функции сразу после ее определения является характерным для языка JavaScript. Программный код, выполняемый в частном пространстве имен, предваряется текстом
<b>«(function() {</b><b>}());</b><b>invocation</b><b>namespace</b>После того как модуль окажется заперт внутри функции, ему необходим некоторый способ экспортировать общедоступный API для использования за пределами функции модуля. В примере 9.24 функция модуля возвращает конструктор, который тут же присваивается глобальной переменной. Сам факт возврата значения из функции ясно говорит о том, что оно экспортируется за пределы области видимости функции. Модули, определяющие более одного элемента API, могут возвращать объект пространства имен. Для нашего модуля с классами множеств можно было бы написать такой программный код:
<b>// Создает единственную глобальную переменную, хранящую все модули,</b><b>// имеющие отношение к коллекциям</b><b>var collections;</b><b>if (!collections) collections = {};</b><b>// Теперь определить модуль sets</b><b>collections.sets = (function namespace() {</b><b> // Здесь находятся определения различных классов множеств,</b><b> // использующих локальные переменные и функции </b><b> // ... Большая часть программного кода опущена...</b><b> // Экспортировать API в виде возвращаемого объекта пространства имен </b><b> return {</b><b> // Экспортируемое имя свойства : имя локальной переменной </b><b> AbstractSet: AbstractSet,</b><b> NotSet: NotSet,</b><b> AbstractEnumerableSet: AbstractEnumerableSet,</b><b> SingletonSet: SingletonSet,</b><b> AbstractWritableSet: AbstractWritableSet,</b><b> ArraySet: ArraySet</b><b> };</b><b>}());</b>Можно предложить похожий прием, определив функцию модуля как конструктор, который будет вызываться с ключевым словом
<b>new</b><b>var collections;</b><b>if (!collections) collections = {};</b><b>collections.sets = (new function namespace() {</b><b> // ... Большая часть программного кода опущена ...</b><b> // Экспортировать API в объекте this</b><b> this.AbstractSet = AbstractSet;</b><b> this.NotSet = NotSet; // И так далее...</b><b> // Обратите внимание на отсутствие возвращаемого значения.</b><b>}());</b>Если объект глобального пространства имен уже определен, функция модуля может просто присваивать значения свойствам этого объекта и вообще ничего не возвращать:
<b>var collections;</b><b>if (!collections) collections = {};</b><b>collections.sets = {};</b><b>(function namespace() {</b><b> // ... Большая часть программного кода опущена ...</b><b> // Экспортировать общедоступный API в объект пространства имен, созданный выше</b><b> collections.sets.AbstractSet = AbstractSet;</b><b> collections.sets.NotSet = NotSet; // И так далее...</b><b> // Инструкция return не требуется, потому что экспортирование выполняется выше.</b><b>}());</b>Фреймворки, реализующие инструменты загрузки модулей, могут предусматривать собственные методы экспортирования API модулей. Внутри модуля может определяться функция
<b>provides(),</b><b>exports</b>