2010-12-09 16 views

Respuesta

6

Esta es la forma estándar de hacerlo. Vea Matt Snider's analysis del YUI YAHOO.namespace function que usa este mismo cheque (También para ver cómo hacer que sea fácil crear espacios de nombres).

código de Matt, que adaptó de YUI al espacio de nombres de la window objeto en lugar del objeto YAHOO:

window.object_mes_namespace = function() { 
    var a = arguments,  
     o = window, 
     i = 0, 
     j = 0, 
     tok = null, 
     name = null; 

    // iterate on the arguments 
    for (i = 0; i < a.length; i = i + 1) { 
     tok = a[i].split("."); 

     // iterate on the object tokens 
     for (j = 0; j < tok.length; j = j + 1) { 
      name = tok[j];    
      o[name] = o[name] || {}; 
      o = o[name]; 
     } 
    } 

    return o; 
} 

Nota o[name] = o[name] || {}; la línea, que es paralelo a su ejemplo.

1

Esta es la forma preferida.

Pero su extracto no hace nada, a menos que filtre MY_NAMESPACE en otro ámbito, porque MY_NAMESPACE es MY_NAMESPACE.

+1

Ejemplo de "filtración en otro ámbito" - 'window.MY_NAMESPACE = window.MY_NAMESPACE || {}; ' – jball

3

Aunque lo que publicaste se ve comúnmente, personalmente no creo que sea la mejor manera de hacerlo.

  1. MY_NAMESPACE podría evaluar a falso por varias razones que no sean undefined - la variable realmente podría definirse pero tenga 0 o false o un cadena vacía, y que podría terminar sustituyendo este valor.

  2. MY_NAMESPACE podría evaluar a cierto por varias razones que no sean ya de ser un objeto - que podría ser un número distinto de cero o true o una cadena, y esto hará que el script falle en silencio, ya que agregar propiedades a una primitiva fallará sin un error.

Realmente, la mejor manera depende de cuál es su objetivo. Si no desea contaminar una variable/espacio de nombres existente, se debe hacer una verificación typeof y detener si la variable ya está definido, pero no un objeto:

if (typeof MY_NAMESPACE == 'undefined') { 
    // create a new namespace 
    MY_NAMESPACE = {}; 
} 

if (typeof MY_NAMESPACE == 'object') { 
    // go ahead 
} else { 
    // MY_NAMESPACE was already defined, but it is not an object 
    // your script will fail if you continue, so do what you must and stop 
} 

Si su script necesidad trabajo, a ciegas crea el espacio de nombres sin ningún control (por supuesto, no estoy recomendando que hagas esto).


Editar: (en respuesta al comentario de @ jball, pensó que acababa de añadir aquí)

  • Si este espacio de nombres es parte de una biblioteca que se está desarrollando, a continuación, es imprescindible que nombre su espacio de nombres con cuidado para evitar colisiones. Si encuentra una colisión, es mejor simplemente dejar de cargar su biblioteca que mezclar su biblioteca con otra y obtener resultados inesperados.

  • Si este espacio de nombres es solo para su propia aplicación, debería ser bastante sencillo elegir un nombre que no esté siendo utilizado por ninguna biblioteca que esté utilizando.

+0

Si seleccionó un espacio de nombre que colisiona con alguna otra variable o espacio de nombres, ¿cómo maneja todo el código dependiente del espacio de nombres? Solo no lo ejecutes? Afortunadamente, todos los demás JS también tienen un espacio de nombres, y son únicos. Si no, ¿se te ocurre una mejor nomenclatura? – jball

+0

Además, crear ciegamente sin controles significa que puede definir parte de su espacio de nombres y luego sobrescribirlo cuando lo defina/extienda más adelante ... el objetivo de la verificación del espacio de nombres es garantizar que su espacio de nombres solo se crea si no existe, por lo que puede garantizar que toda su funcionalidad js escrita en cualquier cantidad de archivos esté contenida en el espacio de nombres. – jball

+0

@jball: mencioné específicamente que no estoy sugiriendo el enfoque ciego. En cuanto a la definición de partes del espacio de nombres, hay mejores formas de hacerlo que 'namespace || {} '. – casablanca

1

Me gusta el YUI example y lo uso para todas mis aplicaciones. En el tuyo, estás reasignando MY_NAMESPACE sin importar qué, lo cual no es gran cosa, pero prefiero evitar esa tarea si no es necesario.

if (typeof myNamespace == "undefined" || !myNamespace) { 
    var myNamespace = {}; 
} 
+0

Estoy confundido, su cheque es diferente al cheque del código YUI. El código OP está mucho más cerca del estilo YUI de creación del espacio de nombres. – jball

+0

De YUI2 if (typeof YAHOO == "undefined" ||! YAHOO) { var YAHOO = {}; } – brad

+0

verdadero para la variable 'YAHOO', pero no para cómo crea espacios de nombres debajo de él. Volcado de código: 'YAHOO.namespace = function() {var a = arguments, o = null, i, j, d; for (i = 0; i jball