Есть ли “краткий” способ создать пространство имен в JavaScript?

StackOverflow https://stackoverflow.com/questions/13021

  •  08-06-2019
  •  | 
  •  

Вопрос

Я часто сталкивался с сайтами, которые помещают весь свой JavaScript внутрь namespace структура по линиям:

namespaces = { com : { example: { example.com's data} }

Однако безопасная настройка этого по отношению к другим фреймворкам с пространством имен, по-видимому, требует относительно большого объема кода (определяется как > 2 строк).Мне было интересно, знает ли кто-нибудь краткий способ сделать это?Кроме того, существует ли относительно стандартный / непротиворечивый способ его структурирования?Например, является ли com пространство имен напрямую подключено к глобальному объекту или оно подключено через объект пространства имен?

[Править:упс, очевидно {com = { ... } } не получилось бы ничего близкого к тому, что я задумал, спасибо Shog9 за указание на это.]

Это было полезно?

Решение

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

Вот ваш пример, исправленный:

var namespaces = { com: { example: { /* example.com's data */ } } }

Это переменная namespaces присваивается объектный литерал.Объект содержит одно свойство: com, объект с одним свойством: example, объект, который предположительно содержал бы что-то интересное.

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

var com_example_data = { /* example.com's data */ };

Это работает так же хорошо, без бессмысленной иерархии.

Сейчас, если вы на самом деле хотеть чтобы построить иерархию, вы можете попробовать что-то вроде этого:

com_example = com_example || {};
com_example.flags = com_example.flags || { active: false, restricted: true};

com_example.ops = com_example.ops || (function()
    {
       var launchCodes = "38925491753824"; // hidden / private
       return {
         activate: function() { /* ... */ },
         destroyTheWorld: function() { /* ... */ }
       };
    })();

...который, ИМХО, достаточно лаконичен.

Другие советы

Вот интересная статья Питера Мишо о Пространство имен Javascript.Он обсуждает 3 различных типа пространства имен Javascript:

  1. Пространство имен с префиксом
  2. Пространство имен одного объекта
  3. Пространство имен вложенных объектов

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

Питер даже зашел так далеко, что указал на то, что у некоторых из них есть соображения производительности.Я думаю, что было бы интересно обсудить эту тему, учитывая, что новые планы ECMAScript Harmony отказались от планов 4.0 в отношении пространства имен и упаковки.

Я стараюсь следовать соглашению Yahoo о создании одного родительского объекта в глобальной области видимости, который содержал бы все;

var FP = {};
FP.module = {};
FP.module.property = 'foo';

Чтобы убедиться, что вы не перезаписываете существующий объект, вы должны сделать что-то вроде:

if(!window.NameSpace) {
    NameSpace = {};
}

или

var NameSpace = window.NameSpace || {};

Таким образом, вы можете поместить это в начало каждого файла вашего приложения / веб-сайта, не беспокоясь о перезаписи объекта пространства имен.Кроме того, это позволило бы вам писать модульные тесты для каждого файла по отдельности.

Тот Самый Библиотека ЮИ в библиотеке есть код, который обрабатывает пространство имен с помощью функции, которая может показаться вам предпочтительной.Другие библиотеки также могут делать это.

В качестве альтернативы точке или подчеркиванию вы могли бы использовать символ знака доллара:

var namespaces$com$example = "data"; 

Мне тоже нравится это (Источник):

(function() {
    var a = 'Invisible outside of anonymous function';
    function invisibleOutside() {
    }

    function visibleOutside() {
    }
    window.visibleOutside = visibleOutside;

    var html = '--INSIDE Anonymous--';
    html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
    html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
    contentDiv.innerHTML = html + '<br/><br/>';
})();

var html = '--OUTSIDE Anonymous--';
html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
contentDiv.innerHTML += html + '<br/>';​

Используйте объектный литерал и либо this объект или явное имя для создания пространства имен на основе родственных свойств локальной переменной, которая содержит функцию.Например:

var foo = { bar: function(){return this.name; }, name: "rodimus" }
var baz = { bar: function(){return this.name; }, name: "optimus" }

console.log(foo.bar());
console.log(baz.bar());

Или без явного name собственность:

var foo = { bar: function rodimus(){return this; } }
var baz = { bar: function optimus(){return this; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Или без использования this:

var foo = { bar: function rodimus(){return rodimus; } }
var baz = { bar: function optimus(){return optimus; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Используйте RegExp или Object функции конструктора для добавления свойств имени к переменным счетчика и другим распространенным именам, затем используйте hasOwnProperty тест для проверки:

 var foo = RegExp(/bar/);
 
/* Add property */
foo.name = "alpha";

document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "&#09;");

/* Check type */
if (foo.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "&#09;");
  }

/* Fallback to atomic value */
else 
  {
  foo = "baz";
  }

var counter = Object(1);

/* Add property */
counter.name = "beta";

if (counter.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["counter", Number(counter), counter.name] + "</pre>").replace(/,/g, "&#09;");
  } 
else 
  {
  /* Fallback to atomic value */
  counter = 0;
  }

DOM использует следующее соглашение для определения пространства имен HTML и SVG элементов интерфейса:

  • HTMLTitleElement Элемент
  • SVGTitleElement Элемент
  • SVGScriptЭлемент
  • HTMLScriptЭлемент

Ядро JavaScript использует прототипы для создания пространства имен toString метод как простая форма полиморфизма.

Ссылки

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top