2008-12-10 9 views
18

¿Cómo puedo emular las clases (y los espacios de nombres) en JavaScript?¿Cómo puedo emular "clases" en JavaScript? (con o sin una biblioteca de terceros)

Necesito crear una biblioteca de JavaScript y tengo experiencia limitada con el idioma. Siempre pensé que tenía soporte nativo para las clases, pero está menos relacionado con Java de lo que había supuesto. Parece que todo en JavaScript es en realidad una función.

Lo que he descubierto hasta ahora tiene mucho sentido, ya que es un lenguaje dinámico débilmente tipado, pero esto lo hace un poco diferente para las personas que están acostumbradas a tener un lenguaje fuertemente tipado y usar un compilador para detectar nuestros errores :)

Principalmente trabajo en C# y Java, y esperaba algo sintácticamente similar para que la biblioteca se vea familiar para nuestros otros desarrolladores de C# que tendrán que mantenerla.

Tengo el siguiente tipo de código que funciona, pero me preguntaba qué otras tomas de desarrollador serían sobre esto. ¿Cuáles son las alternativas? ¿Hay alguna manera que sea mejor? ¿Hay alguna manera que sea más legible?

Entiendo que lo que quiero es algo similar a C# o Java cuando debería aceptar el hecho de que es JavaScript, pero mi objetivo es facilitar la curva de aprendizaje para otros desarrolladores haciéndolo más familiar e intuitivo para ellos.

//Perform the namespace setup (this will actually be done with checking 
//in real life so we don't overwrite definitions, but this is kept short 
//for the code sample). 
var DoctaJonez = new function(); 
DoctaJonez.Namespace1 = new function(); 

/** 
* Class description. 
*/ 
DoctaJonez.Namespace1.SomeClass = function() 
{ 
    /** 
    * Public functions listed at the top to act like a "header". 
    */ 
    this.publicFunction = privateFunction; 

    /** 
    * Private variables next. 
    */ 
    var privateVariable; 

    /** 
    * Finally private functions. 
    */ 
    function privateFunction() 
    { 

    } 
} 

//Create an instance of the class 
var myClass = new DoctaJonez.SomeClass(); 

//Do some stuff with the instance 
myClass.publicFunction(); 

Respuesta

1

Por ejemplo, en http://mckoss.com/jscript/object.htm.

Encontrarás un montón de ejemplos cuando busques en google "JavaScript orientado a objetos". Al echar un vistazo a los marcos de JavaScript populares como Ext JS, tendrá una idea de estos conceptos y cómo se aplican en la práctica.

1

mepcotterell proporciona buenos enlaces, pero me gustaría añadir que personalmente prefiero ver los espacios de nombres como objetos, es decir, DoctaJonez.Namespace1 = {};.

+0

No sabía que pudieras hacer eso, eso se ve mucho más elegante. Gracias por la entrada :) +1 –

9

Para una comprensión general de programación orientada a objetos en JavaScript que no se puede hacer nada mejor que leer Douglas Crockford:

Para los aficionados al Dojo (y para las técnicas generales) Neil Roberts tiene buenos artículos:

con sabor de vainilla dojo.declare() es probablemente el fundamento programación orientada a objetos más avanzada en las bibliotecas convencionales en torno. Soy parcial, pero no tome mi palabra para eso.Aquí hay ejemplos sobre cómo usarlo.

Un objeto con sabor de vainilla:

// Let's define a super simple class (doesn't inherit anything). 
dojo.declare("Person", null, { 
    // Class-level property 
    answer: 42, 

    // Class-level object property 
    name: {first: "Ford", last: "Prefect"}, 

    // The constructor, duh! 
    constructor: function(age){ 
    this.age = age; // instance-level property 
    }, 

    // A method 
    saySomething: function(verb){ 
    console.log("I " + verb + " " + 
     this.name.first + " " + this.name.last + "!" + 
     " -- " + this.answer); 
    }, 

    // Another method 
    passportControl: function(){ 
    console.log("I am " + this.age); 
    } 
}); 

Ejemplo de uso:

// A fan of Ford Perfect 
var fan = new Person(18); 
fan.saySomething("love"); // I love Ford Perfect! -- 42 
fan.passportControl(); // I am 18 

herencia individual es fácil:

// Let's create a derived class inheriting Person 
dojo.declare("SuperAgent", Person, { 
    // Redefine class-level property 
    answer: "shaken, not stirred", 

    // Redefine class-level object property 
    name: {first: "James", last: "Bond"}, 

    // The constructor 
    constructor: function(age, drink){ 
    // We don't need to call the super class because 
    // it would be done automatically for us passing 
    // all arguments to it. 

    // At this point "age" is already assigned. 

    this.drink = drink; // Instance-level property 
    }, 

    // Let's redefine the method 
    saySomething: function(verb){ 
    // Let's call the super class first 
    this.inherited(arguments); 
    // Pay attention: no need for extra parameters, or any extra code, 
    // we don't even name the class we call --- it is all automatic. 
    // We can call it any time in the body of redefined method 

    console.log("Yeah, baby!"); 
    }, 

    shoot: function(){ console.log("BAM!!!"); } 
}); 

Ejemplo de uso:

// Let's create a James Bond-wannabe 
var jb007 = new SuperAgent(45, "Martini"); 
jb007.saySomething("dig"); // I dig James Bond! -- shaken, not stirred 
          // Yeah, baby! 
jb007.passportControl(); // I am 45 
jb007.shoot();    // BAM!!! 

// Constructors were called in this order: Person, SuperAgent 
// saySomething() came from SuperAgent, which called Person 
// passportControl() came from Person 
// shoot() came from SuperAgent. 

Mixins:

// Let's define one more super simple class 
dojo.define("SharpShooter", null, { 
    // For simplicity no constructor 

    // One method to clash with SuperAgent 
    shoot: function(){ 
    console.log("It's jammed! Shoot!"); 
    } 
}); 
basada en Mixin

herencia múltiple:

// Multiple inheritance 
dojo.declare("FakeAgent", ["SuperAgent", "SharpShooter"], { 
    // Let's do it with no constructor 

    // Redefine the method 
    saySomething: function(verb){ 
    // We don't call super here --- a complete redefinition 

    console.log("What is " + verb "? I want my " + this.drink + "!"); 
    }, 
}); 

Ejemplo de uso:

// A fake agent coming up 
var ap = new FakeAgent(40, "Kool-Aid"); 
ap.saySomething("hate"); // What is hate? I want my Kool-Aid! 
ap.passportControl(); // I am 40 
ap.shoot();    // It's jammed! Shoot! 

// Constructors were called in this order: Person, SuperAgent 
// saySomething() came from FakeAgent 
// passportControl() came from Person 
// shoot() came from SharpShooter. 

Como se puede ver, dojo.declare() da todo lo necesario, con un sencillo de usar API: herencia simple directa, herencia múltiple basada en mixin, encadenamiento automático de constructores y supermétodos sin complicaciones.

1

Si usted (y su equipo) está acostumbrado a Java pero necesita crear JavaScript para un sitio web, tal vez debería considerar Google Web Toolkit (GWT). Le permite codificar JavaScript usando Java, que se convierte a JavaScript. No lo he probado, sin embargo.

JavaScript es en realidad un lenguaje bastante genial. Tiene algunos defectos (incluso te permite hacer cosas muy estúpidas), pero con un poco de auto diciplina puedes hacer cosas geniales. JavaScript es realmente objeto -orientada, no tanto clase -orientada, pero puedes hacer muchas de las mismas cosas. No tiene herencia (AFAIK), pero no es estricta en absoluto (una de sus características potentes pero también peligrosas) con la escritura, por lo que encontrará que no es limitante.

+0

Esto suena muy interesante. Investigaré más esto, gracias por el enlace :) –

Cuestiones relacionadas