Декларация пространства имен JavaScript

Я создал класс javascript следующим образом:

var MyClass = (function() {
   function myprivate(param) {
      console.log(param);
   }

   return {
      MyPublic : function(param) {
         myprivate(param);
      }
   };
})();

MyClass.MyPublic("hello");

Приведенный выше код работает, но мой вопрос заключается в том, как я хочу ввести пространство имен в этот класс.

В принципе, я хочу иметь возможность вызвать класс следующим образом:

Namespace.MyClass.MyPublic("Hello World");

Если я добавлю Namespace.MyClass, он выкинет ошибку "Синтаксическая ошибка". Я попытался добавить "window.Namespace = {}", и он тоже не работает.

Спасибо..:)

Ответ 1

Обычно я рекомендую сделать это (предполагая, что Namespace не определен в другом месте):

var Namespace = {};
Namespace.MyClass = (function () {
  // ...
}());

Более гибкий, но более сложный подход:

var Namespace = (function (Namespace) {
   Namespace.MyClass = function() {

       var privateMember = "private";
       function myPrivateMethod(param) {
         alert(param || privateMember);
       };

       MyClass.MyPublicMember = "public";
       MyClass.MyPublicMethod = function (param) {
          myPrivateMethod(param);
       };
   }
   return Namespace
}(Namespace || {}));

Это построит Namespace.MyClass, как указано выше, но не полагается на уже существующий Namespace. Он будет объявлять и создавать его, если он еще не существует. Это также позволяет загружать несколько элементов Namespace параллельно в разных файлах, порядок загрузки не имеет значения.

Подробнее: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

Ответ 2

YUI имеет хороший метод для объявления пространств имен

if (!YAHOO) {
        var YAHOO = {};
}

YAHOO.namespace = function () {
    var a = arguments,
        o = null,
        i, j, d;
    for (i = 0; i < a.length; i = i + 1) {
        d = ("" + a[i]).split(".");
        o = YAHOO;
        for (j = (d[0] == "YAHOO") ? 1 : 0; j < d.length; j = j + 1) {
            o[d[j]] = o[d[j]] || {};
            o = o[d[j]];
        }
    }
    return o;
}

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

YAHOO.namespace("MyNamespace.UI.Controls")

MyNamespace.UI.Controls.MyClass = function(){};
MyNamespace.UI.Controls.MyClass.prototype.someFunction = function(){};

Этот метод действительно автономный и может быть легко адаптирован к вашему приложению. Просто найдите и замените "YAHOO" своим пространством имен приложений, и у вас будет что-то вроде MyOrg.namespace. Хорошая вещь с этим методом заключается в том, что вы можете объявлять пространства имен на любой глубине без необходимости создания объекта массивы между ними, например, для "UI" или "Controls"

Ответ 3

Краткий способ сделать то, что вы просите, создать "пространство имен" в качестве литерала объекта следующим образом:

var Namespace = {
    MyClass : (function() {
        ... rest of your module
    })();
};

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

Ответ 4

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

(function(){
   namespace("MyClass", MyPublic);

   function MyPublic(x){
     return x+1;
   }
})();

Он также поддерживает автоматическое вложение

namespace("MyClass.SubClass.LowerClass", ....)

Генерирует необходимую иерархию объектов, если MyClass, SubClass еще не существует.

Ответ 5

bob.js имеет хороший синтаксис для определения пространства имен JavaScript:

bob.ns.setNs('myApp.myMethods', {
    method1: function() {
        console.log('This is method 1');
    },
    method2: function() {
        console.log('This is method 2');
    }
});
//call method1.
myApp.myMethods.method1();
//call method2.
myApp.myMethods.method2();

Ответ 6

(function($){

    var Namespace =
{
    Register : function(_Name)
    {
        var chk = false;
        var cob = "";
        var spc = _Name.split(".");
        for(var i = 0; i<spc.length; i++)
        {
            if(cob!=""){cob+=".";}
            cob+=spc[i];
            chk = this.Exists(cob);
            if(!chk){this.Create(cob);}
        }
        if(chk){ throw "Namespace: " + _Name + " is already defined."; }
    },

    Create : function(_Src)
    {
        eval("window." + _Src + " = new Object();");
    },

    Exists : function(_Src)
    {
        eval("var NE = false; try{if(" + _Src + "){NE = true;}else{NE = false;}}catch(err){NE=false;}");
        return NE;
    }
}
    Namespace.Register("Campus.UI.Popup")
    Campus.UI.Popup=function(){
        defaults={
            action:'',
            ispartialaction:'',
            customcallback:'',
            confirmaction:'',
            controltoupdateid:'',
            width:500,
            title:'',
            onsubmit:function(id){
                var popupid=id+"_popupholder";
                if(this.ispartialaction){
                    $.ajax({
                        url:this.action,
                        type:"Get",
                        context:this,
                        success:function(data){
                            $('#'+id).parents('body').find('form').append("<div id'"+popupid+"'></div>");
                            var ajaxContext=this;
                            $("#"+popupid).dialog({
                                autoopen:false,
                                model:true,
                                width:this.width,
                                title:this.title,
                                buttons:{
                                    "Confirm":function(){
                                        if(ajaxContext.customcallback==''){
                                            var popupform=$(this).find("form");
                                            if(popupform.isValid()){
                                                $.post(ajaxContext.confirmaction,popupform.serialize(),function(d){
                                                    if(d!='')
                                                    {
                                                        $.each(d.Data,function(i,j){
                                                            switch(j.Operation)
                                                            {
                                                                case 1:
                                                                    if($('#'+j.ControlClientID).is("select"))
                                                                    {
                                                                        $('#'+j.ControlClientID).val(j.Value);
                                                                        $('#'+j.ControlClientID).change();
                                                                    }
                                                                    else if($('input[name="'+j.ControlClientID+'"]').length>0)
                                                                    {
                                                                        $('input[name="'+j.ControlClientID+'"][value="'+j.Value+'"]').prop("checked",true);
                                                                    }
                                                                    break;
                                                                case 2:
                                                                    if($('#'+j.ControlClientID).is("select"))
                                                                    {
                                                                        $('#'+j.ControlClientID).append("<option selected='selected' value=\""+j.Value+"\">"+j.Text+"</option>");
                                                                    }
                                                                    else
                                                                    {
                                                                        var len=$('input[name="'+j.ControlClientID+'"]').length;
                                                                        $('#'+j.ControlClientID+"list").append('<li><input type="checkbox" name="'+j.ControlClientID+'" value="'+j.Value+'" id="ae'+j.ControlClientID+len+'"/><label for "ae'+j.ControlClientID+len+'">'+j.Text+'</label>');
                                                                    }
                                                                    break;
                                                                case 0:
                                                                    $('#'+j.ControlClientID).val(j.Value);
                                                                    breakl
                                                                default:break;
                                                            }
                                                        });                                                                     

                                                        popupform.parent().dialog("destroy").remove();
                                                        $("#"+ajaxContext.controltoupdateid).change();
                                                    }
                                                });
                                            }
                                        }
                                        else
                                        {
                                            executeByFunctionName(ajaxContext.customcallback,window,new Array());
                                        }
                                    },
                                    "Cancel":function(){
                                        $(this).dialog("close");
                                    }
                                }
                            });
                            $("#"+popupid).dialog("open");
                            $("#"+popupid).empty().append(data);
                        },
                        error:function(e)
                        {
                            alert(e);
                        }
                    });
                }
                else
                {
                    var frm=document.createElement("form");
                    frm.id="CampusForm";
                    frm.name="CampusForm";
                    frm.action=this.action;
                    frm.method="post";
                    var arr=$($("#"+id).closest("body").find("form")).serializeArray();
                    $.each(arr,function(i,j){
                        var hidd=document.createElement("input");
                        hidd.type="hidden";
                        hidd.name=j.name;
                        hidd.value=j.value;
                        frm.appendChild(hidd);});
                    document.appendChild(frm);
                    frm.submit();
                }
            }
        },
        clicksubmit=function(){
            var opts=$(this).data("CampusPopup");
            opts.onsubmit($(this).attr("id"));
            return false;
        };
        return
        {
            init:function(opt){
                var opts=$.extend({},defaults,opt||{});
                $(this).data('CampusPopup',opts);
                $(this).bind("click",clicksubmit);
            }};
    }();
    $.extend({CampusPopup:Campus.UI.Popup.init});
})(jQuery)

Ответ 7

Автоматизация объявления пространств имен в javascript очень проста, как вы можете видеть:

var namespace = function(str, root) {
    var chunks = str.split('.');
    if(!root)
        root = window;
    var current = root;
    for(var i = 0; i < chunks.length; i++) {
        if (!current.hasOwnProperty(chunks[i]))
            current[chunks[i]] = {};
        current = current[chunks[i]];
    }
    return current;
};

// ----- USAGE ------

namespace('ivar.util.array');

ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);

namespace('string', ivar.util);

ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo); 

Попробуйте: http://jsfiddle.net/stamat/Kb5xY/ Сообщение в блоге: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/

Ответ 8

Это шаблон дизайна, который я использую, который позволяет вложенные пространства имен, а также добавлять в пространство имен позже (даже из отдельного файла JS), чтобы вы не загрязняли глобальное пространство имен:

Пример: JsFiddle

(function ($, MyObject, undefined) {    
    MyObject.publicFunction = function () {
        console.log("public");
    };

    var privateFunction = function () {
        console.log("private");
    };

    var privateNumber = 0;
    MyObject.getNumber = function () {
        this.publicFunction();
        privateFunction();
        privateNumber++;
        console.log(privateNumber);
    };

    // Nested namespace
    MyObject.nested = MyObject.nested || {};
    MyObject.nested.test = function (text) {
        console.log(text);
    };    
}(jQuery, window.MyObject = window.MyObject || {}));

// Try it
MyObject.getNumber();
MyObject.nested.test('Nested');

Вот как добавить в MyObject из другого файла JavaScript:

(function ($, MyObject, undefined) {
    MyObject.newFunction = function () {
        console.log("Added");
    };
}(jQuery, window.MyObject = window.MyObject || {})); 
// Pass `jQuery` to prevent conflicts and `MyObject` so it can be added to, instead of overwritten

Этот ресурс помог мне узнать все о различных шаблонах проектирования JS: http://addyosmani.com/resources/essentialjsdesignpatterns/book/