Sé, esto es a menudo discutido. Pero después de buscar alrededor como alguien del siglo 19, necesito un poco de asesoramiento. Yo no tengo ningún problema declarando un «espacio de nombres», pero cuando se trata de un prototipo.foo función, me quedé. He encontrado una manera, pero no me gusta:

Namespace = {}
Namespace.obj = function() {
    this.foo="bar";
}
Namespace.obj.prototype.start = function() {
    this.foo="fubar";
}

blah = new Namespace.obj();
blah.start();

Ahora, ya que yo soy un poco neurótica en el caso de secuencias de comandos, me gustaría tener algo como esto:

Namespace = {
    obj: function() {
        this.foo="bar";
    },
    obj.prototype.start: function(tabinst) {
        this.foo="fubar";
    }
}
...

Pero luego se tira un error:
«Uncaught SyntaxError: testigo Inesperado .»

Sé, esto es estética, pero creo que tiene que haber un método mejor de declarar un «espacio de nombres» que contiene una clase y prototipos de funciones.

3 Comentarios

  1. 33

    La forma en que me gustaría hacer es el uso de la «El patrón del módulo».

    Básicamente encapsular todo su «Módulo» de la lógica en un auto de ejecución de la función que devuelve un objeto de tener sus clases, funciones, variables, etc… Piense en el valor de retorno como exponer el Módulo API.

    Namespace = (function () {
        /** Class obj **/
        var obj = function () {
            this.foo = 'bar';
        };
        obj.prototype = {
            start: function () {
                this.foo = 'fubar';
            }
        };
    
        /** Class obj2 **/  
        var obj2 = function () {
            this.bar = 'foo'
        };
        obj2.prototype = {
            start: function () {
                this.bar = 'barfoo';
            },
            end: function () {
                this.bar = '';
            }
        };
        return {
            obj : obj,
            obj2: obj2
        };
    })();
    
    var o = new Namespace.obj()
    o.start()

    A fin de encapsular «obj» los métodos de la clase y constructor podríamos hacer lo siguiente:

    /** Class obj **/
    var obj = (function () {
        /** class Constructor **/
        var obj = function () {
            this.foo = 'bar';
        };
        /** class methods **/
        obj.prototype = {
            start: function () {
                this.foo = 'fubar';
            }
        };
        return obj;
    })();

    También hay una importante característica que viene gratis el uso de este patrón, que es el «variables Privadas», considere lo siguiente:

    /** Class Foo **/
    var Foo = (function () {
        //Private variables
        var private_number = 200
        /** class Constructor **/
        var Foo = function () {
            this.bar = 0;
        };
        /** class methods **/
        Foo.prototype = {
            add: function () {
                this.bar += private_number;
            }
        };
        return Foo;
    })();
    
    foo = new Foo();
    alert(foo.bar); //0
    foo.add(); 
    alert(foo.bar);//200
    alert(foo.private_number) //undefined
    • Buen enfoque, +1.
    • Actualmente, Amjad, esto es genial. Pero ahora estoy tropezando de nuevo. No lo veo a la derecha: Con este enfoque no es posible hacer un espacio de Nombres.bla() función que se separa de forma obj?
    • Si entiendo tu pregunta, sólo tiene que añadir un blah función al objeto de devolución: . . return { obj : obj, obj2: obj2, blah: function () {/* do something */} };
    • Amjad, muchas gracias. Esto es exactamente lo que yo quería! Ahora que lo tengo.
  2. 3

    Sí, porque, no se puede utilizar este tipo de encadenamiento en un objeto de la declaración de

    obj.prototipo o obj.algo de aquí, porque el lenguaje se ve obj como un no-objeto de valor. Se puede fingir un efecto como este

    Namespace = {};
    
    Namespace.obj =function() {
            this.foo="bar";
    };
    
    Namespace.obj.prototype.start = function(tabinst) {
            this.foo="fubar";
    };
    
    console.log( Namespace.obj.prototype );

    (ver este violín http://jsfiddle.net/WewnF/ )

    EDIT: Wow, me acabo de dar cuenta de que lo que me dijo que ya estaba dentro de la pregunta. I ‘m lo siento, no se dio cuenta de que antes… Bueno, la forma en que se describe a sí mismo es el método correcto para lograrlo.

    De lo contrario se puede volver a escribir el código como este -, pero no es exactamente lo que usted ‘re después y no funcionan de la misma (desde obj no ser una función propia y usted tendrá que llamar a su principal función como esta obj.main(); )

    Namespace = {
        obj: {
              main : function() {
                   this.foo="bar";
              },
              prototype : {
                 start: function(tabinst) {
                 this.foo="fubar";
                 }
              }
        }
    }

    EDIT 2: Consulte este violín http://jsfiddle.net/NmA3v/1/

    Namespace = {
        obj: function() {
            this.foo="bar";
        },
        prototype: {
            obj : {
                start : function( hi ) {
                     alert( hi ); 
                }  
            }
    
        },
    
        initProto : function(){
            for( var key in Namespace )
            {
                if( key !== "prototype" )
                {
                    for( var jey in Namespace.prototype[ key ] )
                        Namespace[ key ].prototype[ jey ] =  Namespace.prototype[ key ][ jey ];  
                }
            }
        }
    }
    
    Namespace.initProto();
    
    console.log( Namespace.obj);
    
    var test  = new Namespace.obj();
    
    test.start( "Hello World" );

    Esto tendrá el mismo efecto.
    Explicación : estamos declarando nuestra objetos como propiedades normales-funciones y, a continuación, usar un patrón prototipo objeto de que los contenedores de objetos con el mismo nombre que los de arriba, por ejemplo para cada espacio de Nombres.obj, también hay un espacio de Nombres.el prototipo.obj que contiene las funciones que desea agregar en la cadena de prototipos.

    a continuación, con el espacio de nombres.protoInit(), nos recorrer todas las propiedades y el extracto de las funciones del espacio de Nombres.prototipo[ clave ] y agregarlos al espacio de Nombres[ clave ].prototipo con éxito la ampliación del objeto prototipo! Un poco ortodoxo, pero funciona!

    • El primer fragmento de código en su edición no funcionará como se podría pensar. obj.main y obj.prototype son dos diferentes funciones independientes. Sí, this se refieren al mismo objeto si se les llame sin new, pero sólo porque se refiere a window. Así que usted tendrá que hacer foo global.
    • El segundo ejemplo de los límites de Namespace a sólo contienen una «clase» que de alguna manera se anula el propósito del espacio de nombres.
    • Estás en lo correcto para el primer ejemplo, y me siento estúpido por no darse cuenta de esto antes, pero no estoy de acuerdo sobre el segundo. ¿Por qué limitarse sólo a una «clase» ? Si usted usa más objetos, va a iterar a través de ellos y de darles la correcta prototipo de valores.
    • Ah cierto, tienes obj dentro de prototype…. Lo echaba de menos. Lo siento por eso. Aún diría que este no es un enfoque directo.
  3. 3

    Sólo por diversión y para ampliar la respuesta anterior. Un poco más de notación de objetos orientados basado en el espacio de nombres anidados

    var NS = {};
    
    //Class List
    NS.Classes = {
      Shape: (function(){
        //Private
        var whateveryouwishboss = false;
    
        //Public
        var Shape = function(x,y,w,h){
          this.x = x;
          this.y = y;
          this.w = w;
          this.h = h;
        };
        Shape.prototype = {
          draw: function(){
            //... Im on prototype Shape 
          }
        }
        return Shape;
      })(),
      Person: (function(){
        //....
      })()
    }
    
    ///////Let the games begin
    
    var rect = new NS.Class.Shape(0,0,10,10);
    rect.draw()

Dejar respuesta

Please enter your comment!
Please enter your name here