2012-06-10 27 views
9

He leído que crear un espacio de nombres para proyectos de JavaScript ayuda a reducir los conflictos con otras bibliotecas. Tengo un código con muchos tipos diferentes de objetos para los que he definido funciones de constructor. ¿Es una buena práctica poner estos dentro del espacio de nombres también?constructores dentro de un espacio de nombres

Por ejemplo:

var shapes = { 
    Rectangle: function(w, h) { 
     this.width = w; 
     this.height = h; 
    } 
}; 

que se puede llamar a través de:

var square = new shapes.Rectangle(10,10); 
+3

Creo que es una buena idea –

+0

Su constructor, que es una función, se convierte en * expresión de función * en lugar de * declaración de función * si la asigna a una propiedad de objeto en un "espacio de nombres" en lugar de simplemente escribir 'función Rectángulo (w, h) {}'. Esto tiene pequeñas diferencias: https: //developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions Aparte de eso, no contamina el espacio de nombres global, lo cual es bueno, como otros han señalado. – caw

Respuesta

4

Este espacio de nombres se llama "Singleton pattern" y es uno de los principales patrones recomendados por el famoso "Gang of Four" libro de patrones de diseño.

Desde el gran (y gratis) Learning JavaScript Design Patterns libro:

Clásicamente, el patrón Singleton se puede implementar mediante la creación de una clase con un método que crea una nueva instancia de la clase si uno no lo hace existe. En el caso de que una instancia ya exista, simplemente devuelve una referencia a ese objeto. El patrón Singleton se conoce como porque restringe la creación de instancias de una clase a un solo objeto.

En JavaScript, los singletons sirven como un proveedor de espacio de nombres que aísla el código de implementación del espacio de nombres global para proporcionar un único punto de acceso para las funciones.

Ellos pueden tomar en un número de diferentes formas, pero en su forma más básica, un Singleton podría ser implementado como un objeto literal agrupados con sus funciones y propiedades relacionadas ...

Así que sí , es un concepto bien utilizado en muchos lenguajes de programación y es excelente para evitar colisiones de objetos en espacios de nombres globales en JavaScript.

Consulte también: Simplest/Cleanest way to implement singleton in JavaScript?

+1

Genial. Muchas gracias. También gracias por los enlaces. Simplemente no había visto ningún ejemplo de alguien que llama 'nuevo' para una función en un espacio de nombres y me preguntaba si había una razón para eso. – Joe

+0

No hay razón por la que se me ocurra. La nueva función es la herencia prototípica de JavaScript, que a menudo se usa en la práctica como más una herencia de clase. La mayoría de los ejemplos que verá definen solo una única "clase", pero si está tratando de organizar muchos de ellos, el patrón singleton es igualmente útil. – buley

+2

@joe por supuesto, no se considera patrón singleton si el literal del objeto contiene constructores ;-) –

2

Sí. Debe contaminar el espacio de nombres global lo menos posible

2

Sí, eso es una buena idea, porque se evita la molestia y confusión causada por la contaminación del espacio de nombres global. Aunque yo personalmente cambiaría shapes a shape, entonces podría tener un shape.Rectangle, lo que tiene un poco más de sentido para mí (después de todo, un rectángulo es solo un objeto).

1

Además de no contaminar el espacio de nombres, sino que también le permite realizar la comprobación de tipos de familia:

function doSomethingTo(shape) { 
    var shapeName, validArg; 

    for (shapeName in shapes) { 
    validArg = validArg || shape instanceof shapes[shapeName]; 
    } 

    if (!validArg) throw "Argument is not a shape."; 
} 
5

Ésta es generalmente una buena idea; Además, si los objetos requieren un conjunto de funciones compartidas que no debe ser expuesto se puede envolver a todos ellos dentro de un cierre, como un módulo:

var shapes = (function() { 
    // private variables 
    var foo = 0; 

    // private function 
    function get_area(w, h) 
    { 
    return w * h; 
    } 

    return { 
    Rectangle: function(w, h) { 
     this.width = w; 
     this.height = h; 
     // call private function to determine area (contrived example) 
     this.area = get_area(w, h); 
    } 
    } 
}()); 

var s = new shapes.Rectangle(100, 5); 
Cuestiones relacionadas