2010-03-24 54 views
28

que creó una clase de JavaScript de la siguiente manera:JavaScript Espacio de nombres

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

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

MyClass.MyPublic("hello"); 

El código anterior funciona, pero mi pregunta es, ¿si quiero introducir espacio de nombres a esa clase.

Básicamente quiero ser capaz de llamar a la clase como esta:

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

Si he añadido Namespace.MyClass, que va a tirar de error "Error de sintaxis". Intenté agregar "window.Namespace = {}" y tampoco funciona.

Gracias .. :)

+0

Duplicado exacto ... http://stackoverflow.com/questions/881515/javascript-namespace-declaration –

Respuesta

43

Por lo general, yo recomendaría hacer esto (suponiendo Namespace no se define en otra parte):

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

A más flexible, pero más complejo, enfoque:

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 || {})); 

Esto construye Namespace.MyClass que el anterior, pero no confía en Namespace ya existente. Lo declarará y creará si aún no existe. Esto también le permite cargar varios miembros de Namespace en paralelo en diferentes archivos, el orden de carga no tendrá importancia.

Para más: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

+2

+1, buen enfoque! – CMS

+0

¿Cuál es el significado de '(Namespace || {});' al final? –

3

Una forma sucinta que ver lo que está pidiendo es crear "espacio de nombres" como un objeto literal de esta manera:

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

Esto podría causar conflictos si se quería adjunte otros detalles al Espacio de nombres en otros archivos, pero puede evitarlo creando siempre el Espacio de nombres primero, y luego estableciendo los miembros explícitamente.

9

YUI tiene un método agradable para los espacios de nombres que declaran

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; 
} 

colocan por encima de cualquier función que desea espacio de nombres como esto:

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

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

Este método es realmente autónomo y se puede adaptar fácilmente a su aplicación. Solo encuentra y reemplaza "YAHOO" con el espacio de nombres base de tu aplicación y tendrás algo como MyOrg.namespace. Lo bueno de este método es que se puede declarar espacios de nombres en cualquier profundidad sin tener que crear matrices de objetos en el medio, como por "interfaz de usuario" o "Controles"

2

Pedido del namespace library, es muy ligero y fácil de implementar .

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

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

Soporta la anidación de forma automática, así

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

generaría la jerarquía de objetos necesarios, si MiClase, subclase no existiera ya.

1

bob.js tiene buena sintaxis para definir JavaScript espacio de nombres:

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(); 
0

La automatización de declaración de espacios de nombres en javascript es muy simple como se puede ver:

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); 

Pruébelo: http://jsfiddle.net/stamat/Kb5xY/ Blog post: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/

0

Este es el patrón de diseño que uso que permite el nombre anidado espacios, así como la adición al espacio de nombres más adelante (incluso desde un archivo JS separada) por lo que no contamina el espacio de nombres global:

Ejemplo: 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'); 

aquí es cómo añadir a MyObject de otro JavaScript archivo:

(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 

Este recurso ayudado a aprender todo acerca de los diferentes patrones de diseño JS: http://addyosmani.com/resources/essentialjsdesignpatterns/book/

1
(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) 
Cuestiones relacionadas