2012-05-26 13 views
9

Estoy intentando averiguar cómo construir mis clases Javascript (u objetos singleton) correctamente.¿Cuál es la forma correcta de crear una clase de Javascript?

var obj = new Object(); 
obj.foo = 'bar'; 
obj.method = function() { ...} 

var obj = { 
    foo : 'bar', 
    method : function() { ...} 
} 

var obj = function(){} 
obj.prototype = { 
    foo : 'bar', 
    method: function() { ... } 
} 

Quiero ser capaz de establecer un par de propiedades y asignar los métodos disponibles. También me gustaría poder usar cosas como mixins en los objetos para poder extender estos objetos con cosas como events.

+5

Regla # 1: Nunca use 'new Object()'. – Ryan

+0

@minitech, ¿estás seguro? Deben haberlo hecho por alguna razón. – Xeoncross

+0

@Xeoncross: no es que yo sepa. :-) –

Respuesta

8

Estoy tratando de averiguar cómo construir mis clases Javascript (u objetos singleton) correctamente.

Hay una gran diferencia entre esos ("clases" y objetos singleton). Sus primeros ejemplos son objetos únicos (singletons). Su tercer (último) ejemplo crea una función de constructor que le permitirá crear varios objetos que comparten el mismo prototipo. Yo recomendaría aumentar la propiedad prototype en la función constructora en lugar de reemplazarlo como que estás haciendo, por ejemplo:

var Thingy = function() { // Or use a function declaration rather than expression 
    // Optional initialization code here 
}; 
Thingy.prototype.foo = 'bar'; 
Thingy.prototype.method = function() { 
    // Method code here 
}; 

(. Las funciones constructoras, por convención, comienzan con una letra mayúscula)

Que usa (función singleton o constructor) depende de lo que necesite.

A partir de ES2015 (también conocido como "ES6"), es más simple, aunque no hay una nueva sintaxis para definir una propiedad de prototipo que no es un método (su foo); es probable que haya en ES2017 o ES2018, una vez this proposal se mueve hacia adelante, pero hasta entonces:

class Thingy { 
    constructor() { 
     // Optional initialization code here 
    } 
    method() { 
    // Method code here 
    } 
} 
Thingy.prototype.foo = 'bar'; 

Si usted necesita para entrar en jerarquías de herencia, en la sintaxis ES5 de edad hay un poco de plomería involucrados:

var Base = function() { 
}; 
Base.prototype.method = function(arg1) { 
    // ... 
}; 

var Derived = function() { 
    Base.call(this); 
}; 
Derived.prototype = Object.create(Base.prototype); 
Derived.prototype.constructor = Derived; 
Derived.prototype.method = function(arg1) { 
    // Using Base's `method`, if desired, is a bit ugly: 
    Base.prototype.method.call(this, arg1); 
}; 

... por lo que solía ver las bibliotecas interviniendo, como las de Prototype Class, o las mías propias Lineage; aquellos no están actualizados por la sintaxis ES2015, sin embargo, lo que se agradece lo hace francamente fácil:

class Base { 
    method(arg1) { 
     // ... 
    } 
} 
class Derived extends Base { 
    method(arg1) { 
     // Use's the superclass's `method`, if desired, is easy: 
     super.method(arg1); 
    } 
} 

Re el título de su pregunta:

¿Cuál es la forma correcta de crear una clase de Javascript?

Existen varias formas igualmente correctas de crear "clases" de objetos en JavaScript, porque JavaScript es un lenguaje muy flexible. Existen funciones de constructor estándar, funciones de "constructor", Object.create (en entornos habilitados para ES5) que le permiten realizar una herencia prototípica más directa, y muchas otras. Una de las mejores cosas de JavaScript es que puedes elegir tu estilo de "clase".

1

también se puede usar algo como:

function O(x,y) { 
    this.x=x; 
    this.y=y; 
    this.method=function() {...} 
    return this; 
} 

var o=new O(0,0); 
0

Si usted está apuntando un navegador o un entorno que apoye ES5, entonces usted puede hacer esto:

var Person = { 
    foo: ..., 
    bar: ... 
}; 

var Mike = Object.create(Person, { baz: ... }); 
1

Si usted está buscando una solución práctica en lugar de una teórica, es mejor utilizar un marco.

  • Backbone.js tiene todo lo que necesita, incluyendo mixins y un sistema de eventos.

Si necesita algunos widgets también, considerar

Ambos proporcionan una arquitectura limpia y se pueden utilizar sin los widgets, pero requieren un poco más aprendizaje que Backbone.

La estructura de herencia que brindan estos marcos se parece mucho a la clase común (piense en Java). Eso es porque crean objetos especiales internamente que simplemente sirven como prototype s para otros, y por lo tanto toman el rol de clases.

Por ejemplo, cuando se llama Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }), a continuación, Ext crea una function "MyClass", y un objeto anónimo (MyClass.prototype) que contiene los métodos que proporcionan.

Cuestiones relacionadas