¿Cuál es el formato más limpio para escribir objetos javascript?

Actualmente escribo el mío en el siguiente formato

if (Namespace1 == null) var Namespace1 = {};
if (Namespace1.NameSpace2 == null) Namespace1.NameSpace2 = {};

Namespace1.NameSpace2.Class1 = function(param1,param2){
     // define private instance variables and their getters and setters
     var privateParam = param1;
     this.getPrivateParam = function() {return privateParam;}
     this.publicParam1 = param2;
}

Namespace1.Namespace2.Class1.prototype = {
     publicParam1:null,
     publicFunction1:function() {/* Function body*/}
}

Ese formato funciona bien en este momento, ya que el software de documentación de YUI puede analizarlo, y los comentarios y devolver buena documentación. Pero lo que no proporciona es una forma limpia de declarar métodos globales estáticos dentro del espacio de nombres. También me pregunto si también hay una forma más limpia de declarar variables privadas.

Mi pregunta es, ¿hay alguien por ahí que tenga una forma más limpia de definir objetos javascript que esta, y si es así, por qué es mejor su método?

¡Gracias!

1
Zoidberg 26 ago. 2009 a las 23:00

4 respuestas

La mejor respuesta

El patrón del módulo puede ayudarte aquí:

 var Namespace1 = Namespace1 || {};
    Namespace1.Namespace2 = Namespace1.Namespace2 || {};

    Namespace1.Namespace2.Class1 = function(param1, param2) {
        // define private instance variables and their getters and setters
        var privateParam = param1;
        this.getPrivateParam = function() { return privateParam; }
        this.publicParam1 = param2;

        return {
            init: function() {
                alert('hi from Class1');
            }
        }
    } ();

Puede leer más sobre esto aquí: http://yuiblog.com/blog/ 2007/06/12 / module-pattern /

    Namespace1.Namespace2.Class1.init();
5
Olivieri 26 ago. 2009 a las 20:11

Yo uso la siguiente función:

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

Entonces puedo usar esta función para crear un espacio de nombres como este:

$.namespace("jQuery.namespace1");

Una vez que haya creado el espacio de nombres, puedo declarar funciones o lo que quiera dentro de él:

Una función:

$.namespace1.asyncRequest = function() {
    [function body]
};

Una constante:

$.namespace1.OFFSET = 10;

Un objeto:

$.namespace1.request = { requestId: 5, protocol: 'JSON' };

Creo que es simple y elegante :-)

Adios Alex

1
Alex 28 ago. 2012 a las 09:29

Ciertamente, reescribe las dos primeras líneas para esto:

var Namespace1 = Namespace1 || {};
Namespace1.Namespace2 = Namespace1.Namespace2 || {};

El resto de las miradas están bien. La variable privada es más o menos como todos lo hacen. Los métodos estáticos deben asignarse a prototype, como lo ha hecho.

Sin embargo, tenga cuidado al redefinir el prototipo completo para un objeto, ya que evitará un patrón común de herencia basada en prototype. Por ejemplo:

// You inherit like this...
Sub.prototype = new Super();
obj = new Sub();

// Then you overwrite Sub.prototype when you do this:
Sub.prototype = {foo:1, bar:2}

// Instead, you should assign properties to the prototype individually:
Sub.prototype.foo = 1;
Sub.prototype.bar = 2;
1
Triptych 26 ago. 2009 a las 19:42

En primer lugar, si no sabe si Namespace1 está definido, use typeof this.Namespace1 !== "undefined", ya que acceder al espacio de nombres1 arrojará un error si no está definido. Además, las propiedades indefinidas son undefined, no null (aunque undefined == null). Su verificación fallará si algo es realmente nulo . Si no desea usar typeof para verificar si las propiedades no están definidas, use myObject.property === undefined.

Además, su segundo ejemplo tiene una sintaxis no válida. Esto es lo que creo que querías hacer:

Namespace1.Namespace2.Class1.prototype = {
     publicParam1    : null,
     publicFunction1 : function () {/* Function body*/}
};
5
Eli Grey 26 ago. 2009 a las 19:29