2012-04-17 9 views
5

He ignorado el javascript para siempre. Empecé a usar jQuery hace unos años para poder vivir. Pero a medida que comencé a hacer TDD más, ayer decidí sumergirme realmente en javascript (y posiblemente coffeescript después de eso).¿Cómo se expande el espacio de nombres de JavaScript en varios archivos?

En mi aplicación ASP.NET Web Forms tengo muchas páginas y actualmente la mayoría de esas páginas no tienen mucho javascript. Estoy en el proceso de cambiar eso. Estoy usando Jasmine con Chutzpah para crear mis pruebas.

Me estaba moviendo junto con mis pruebas aprobándose y fallando como se esperaba. Pero luego quería crear un espacio de nombres para no pisotear todo el espacio global.

Después de leer este artículo: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

decidí probar y utilizar el patrón de la función anónima autoejecutable: Parte 2 sección (Público & privada) del artículo. Parece tener la mayor flexibilidad y parece encapsular las cosas muy bien.

Tengo una carpeta llamada/Scripts. Debajo de esa carpeta están algunos de los marcos que estoy usando como jQuery, jasmine, (twitter) bootstrap y modernizr. También tengo una subcarpeta llamada/Sitio donde coloco mi código para el sitio en varios archivos basados ​​en la página. (product.js, billing.js, etc.)

En/Scripts/Sitio Agregué una subcarpeta a/Tests (o Specs) que tienen los archivos (product_test.js, billing_tests.js, etc.).

Sin tener espacios de nombres, todo está bien. Tengo un archivo utility.js que creé con una función auxiliar padLeft. Luego usé ese padLeft global en otro archivo .js. Mis pruebas funcionaron y yo estaba feliz. Entonces me decidí a averiguar el espacio de nombres y cambiado mis scripts/Sitio/utility.js para parecerse a:

(function (myns, $, undefined) { 
    //private property 
    var isSomething = true; 

    //public property 
    myns.something = "something"; 

    //public method 
    myns.padLeft = function (str, len, pad) { 
     str = Array(len + 1 - str.length).join(pad) + str; 

     return str; 
    }; 


    //check to see if myns exists in global space 
    //if not, assign it a new Object Literal 
}(window.myns= window.myns|| {}, jQuery)); 

Luego, en mis scripts/Sitio/Pruebas/utility_test.js tengo

/// <reference path="../utility.js" /> 

describe("Namespace myns with public property something", function() { 
    it("Should Equal 'something'", function() { 
     expect(myns.something).toEqual('something'); 
    }); 
}); 

Con esta prueba extremadamente simple, esperaba myns. Algo volvería con el valor de cadena de 'algo'.

No es así. Vuelve undefined.

Entonces, ¿cómo debo usar el espacio de nombres javascript en varios archivos?

Lo siento por la larga introducción, pero pensé que podría ayudar a explicar el por qué de mí hacerlo de esta manera. También puse todo esto porque estoy abierto a escuchar ideas sobre cómo esta configuración es totalmente incorrecta o parcialmente incorrecta, o lo que sea.

Gracias por tomarse el tiempo para leer esta pregunta.

ACTUALIZACIÓN: SOLUCIONADO Gracias a todos por su ayuda. La mayor ayuda provino del comentarista @ T.J. Crowder. No sabía que existía la herramienta jsbin y, después de convencerme de que el código que puse arriba se puso en la herramienta y los resultados fueron los correctos, supe que algo tenía que estar apagado en mi entorno.

El enlace en la respuesta aceptada también me ayudó mucho. Después de ver que la sintaxis y la lógica eran consistentes y funcionables, solo tenía que determinar qué estaba mal con mi configuración. Me avergüenza decir que fui yo quien transfirió jQuery, pero en mi arnés de prueba donde intentaba hacer que esto funcionara, en realidad no estaba usando jQuery. Esto significaba que el módulo no se estaba cargando, por lo que myns nunca se configuró.

Gracias a todos. Esperemos que esto pueda ser útil para alguien en el futuro. Si usa lo anterior, asegúrese de incluir el objeto jQuery. La otra opción es no pasar jQuery y eliminar $ de la lista de param.

+2

Lo que ha demostrado debe funcionar siempre que se incluyan tanto 'utility.js' como' utility_test.js', y en ese orden. Ejemplo: http://jsbin.com/idofog –

+0

gracias por la larga introducción, nos ayuda a descubrir lo que quiere :-) – Philipp

+0

@ T.J.Crowder Gracias. Ese bin funciona pero no puedo ver por qué es diferente en mi entorno. No sabía sobre jsbin, ¡así que gracias por eso también! Voy a intentar algunas cosas en esa caja de arena. –

Respuesta

0

Javascript no tiene espacios de nombres, supongo que tiene problemas con los ámbitos variables y esto es similar a otros idiomas, de lo que está hablando son objetos. Usted podría utilizar

window.myns.something 

La primera función ya está añadiendo el objeto en el objeto de la ventana, y el objeto de la ventana es accesible desde cualquier lugar.

+0

usando una propiedad anidada como esta es una forma común de emular espacios de nombres en Javascript. – Alnitak

+0

Lo sé pero como dijiste, está "emulando" espacios de nombres. Existen grandes diferencias con los espacios de nombres, p. en .NET, pero es similar a los objetos en .NET (excepto cambiar la interfaz en tiempo de ejecución) – Philipp

+0

@PhilippMehrwald Gracias. Debería haber sido más claro al decir "emular espacios de nombres". Con el patrón que estoy buscando, intento evitar el uso de window.myns.something. Incluso el cambio a eso en mi archivo de prueba falló. Así que debo tener algo más equivocado. ¡Gracias! –

1

trate de poner el nombre de la declaración del espacio exterior de la llamada de función:

myns = window.myns || {}; 
(function(myns, $, undefined) { 
    ... 
}(myns, jQuery)); 

Su sintaxis existente parece ser completamente válido, pero romper esa línea puede ayudar a determinar lo que va mal con su alcance variable.

+0

Gracias, lo intenté pero tuve los mismos resultados. Parece que tengo algo más en mal estado. Excavar en él ... –

Cuestiones relacionadas