Как мне объявить пространство имен в JavaScript? - PullRequest
954 голосов
/ 19 мая 2009

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

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

Есть ли более элегантный или лаконичный способ сделать это?

Ответы [ 27 ]

1 голос
/ 05 июля 2018

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

namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);

Попробуйте:

// --- definition ---
const namespace = namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);

// --- Use ----
let myNamespace = namespace("a.b.c");
myNamespace.MyClass = class MyClass {};

// --- see ----
console.log("a : ", a);
1 голос
/ 21 августа 2015

Мы можем использовать его независимо таким образом:

var A = A|| {};
A.B = {};

A.B = {
    itemOne: null,
    itemTwo: null,
};

A.B.itemOne = function () {
    //..
}

A.B.itemTwo = function () {
    //..
}
1 голос
/ 13 июня 2015

Довольно продолжение ответа Ionuț G. Stan, но показывающий преимущества незагроможденного кода с использованием var ClassFirst = this.ClassFirst = function() {...}, который использует преимущества замкнутой области JavaScript для уменьшения помехи в пространстве имен для классов в одном и том же пространстве имен.

var Namespace = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 123;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

var Namespace2 = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 666;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

new Namespace.ClassSecond()
new Namespace2.ClassSecond()

Выход:

Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
0 голосов
/ 06 февраля 2011

Я написал другую библиотеку пространств имен, которая работает немного больше, чем пакеты / модули на других языках. Это позволяет вам создавать пакет кода JavaScript и ссылаться на этот пакет из другого кода:

Файл hello.js

Package("hello", [], function() {
  function greeting() {
    alert("Hello World!");
  }
  // Expose function greeting to other packages
  Export("greeting", greeting);
});

Файл Example.js

Package("example", ["hello"], function(greeting) {
  // Greeting is available here
  greeting();  // Alerts: "Hello World!"
});

Только второй файл должен быть включен в страницу. Его зависимости (файл hello.js в этом примере) будут автоматически загружены, а объекты, экспортированные из этих зависимостей, будут использованы для заполнения аргументов функции обратного вызова.

Соответствующий проект можно найти в Пакетах JS .

0 голосов
/ 13 апреля 2011

Если вы используете Makefile, вы можете сделать это.

// prelude.hjs
billy = new (
    function moduleWrapper () {
    const exports = this;

// postlude.hjs
return exports;
})();

// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;

// clientfile.js
billy.bob();

Я предпочитаю использовать Makefile в любом случае, когда доберусь до 1000 строк, потому что могу эффективно закомментировать большие участки кода, удалив одну строку в make-файле. Это позволяет легко возиться с вещами. Кроме того, с помощью этой техники пространство имен появляется в прелюдии только один раз, поэтому его легко изменить, и вам не нужно повторять его внутри кода библиотеки.

Сценарий оболочки для живой разработки в браузере при использовании make-файла:

while (true); do make; sleep 1; done

Добавьте это как задачу make 'go', и вы сможете 'make go', чтобы ваша сборка обновлялась по мере вашего кода.

0 голосов
/ 20 октября 2016

В JavaScript нет предопределенных методов для использования пространств имен. В JavaScript мы должны создавать свои собственные методы для определения пространств имен. Вот процедура, которой мы следуем в технологиях Oodles.

Зарегистрируйте NameSpace Ниже приводится функция для регистрации пространства имен

//Register NameSpaces Function
function registerNS(args){
 var nameSpaceParts = args.split(".");
 var root = window;

 for(var i=0; i < nameSpaceParts.length; i++)
 {
  if(typeof root[nameSpaceParts[i]] == "undefined")
   root[nameSpaceParts[i]] = new Object();

  root = root[nameSpaceParts[i]];
 }
}

Чтобы зарегистрировать пространство имен, просто вызовите вышеупомянутую функцию с аргументом в качестве пространства имен, разделенного '.' (точка). Например Пусть ваше приложение называется oodles. Вы можете создать пространство имен, используя метод

registerNS("oodles.HomeUtilities");
registerNS("oodles.GlobalUtilities");
var $OHU = oodles.HomeUtilities;
var $OGU = oodles.GlobalUtilities;

В основном это создаст вашу структуру NameSpaces, как показано ниже в бэкэнде:

var oodles = {
    "HomeUtilities": {},
    "GlobalUtilities": {}
};

В приведенной выше функции вы зарегистрировали пространство имен с именами "oodles.HomeUtilities" и "oodles.GlobalUtilities". Чтобы вызвать эти пространства имен, мы создаем переменную, то есть var $OHU и var $OGU.

Эти переменные - не что иное, как псевдоним для инициализации пространства имен. Теперь, когда бы вы ни объявили функцию, которая принадлежит HomeUtilities, вы объявите ее следующим образом:

$OHU.initialization = function(){
    //Your Code Here
};

Выше приведена инициализация имени функции, и она помещается в пространство имен $OHU. и вызывать эту функцию в любом месте файлов сценария. Просто используйте следующий код.

$OHU.initialization();

Аналогично, с другими пространствами имен.

Надеюсь, это поможет.

0 голосов
/ 16 апреля 2015

Моя привычка - использовать функцию myName () в качестве хранилища свойств, а затем var myName в качестве "метода" держателя ...

Является ли это достаточно законным или нет, бей меня! Я все время полагаюсь на свою логику PHP, и все просто работает. : D

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
 (myObj instanceof Function !== false)
 ? Object.create({

     $props: new myObj(),
     fName1: function() { /* code..  */ },
     fName2: function() { /* code ...*/ }
 })
 : console.log('Object creation failed!')
);

if (this !== that) myObj.fName1(); else myObj.fName2();

Вы также можете сделать это «наоборот», чтобы проверить перед созданием объекта, что намного лучше :

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
    (typeof(myObj) !== "function" || myObj instanceof Function === false)
    ? new Boolean()
    : Object.create({
        $props: new myObj(),
        init: function () { return; },
        fName1: function() { /* code..  */ },
        fName2: function() { /* code ...*/ }
    })
);

if (myObj instanceof Boolean) {
    Object.freeze(myObj);
    console.log('myObj failed!');
    debugger;
}
else
    myObj.init();

Ссылка на это: JavaScript: создание объекта с помощью Object.create ()

...