2011-03-29 13 views
11

Estoy trabajando en un proyecto y estoy tratando de escribir código JavaScript orientado a objetos. Acabo de comenzar a leer Douglas Crockford's JavaScript: The Good Parts y rápidamente me estoy dando cuenta de que escribir OOP Java-esque en JavaScript será una tarea difícil.OOP Java-esque en JavaScript y un error de jQuery

algo Hasta ahora, he escrito como el siguiente ...

// index.html 
$(document).ready(function() { 

    $().SetUpElements(); 
}); 

// this is in a different js file 
$.fn.SetUpElements = function() { 

    // do stuff here 
    $().UpdateElement(); 
}; 

// this is in yet another different js file 
$.fn.UpdateElement = function() { 

    // do stuff here 
    var element = new Element(id, name); // continue doing work 
}; 

function Element(id, name) { 

    var id = id; 
    var name = name; 

    // other stuff 
}; 

... la idea es que quiero objetos/funciones a refactorizan y desacoplados tanto como sea posible; Quiero volver a utilizar todo el código que pueda. He difundido una gran cantidad de mi código a través de diferentes archivos .js con la intención de agrupar códigos relevantes específicos, al igual que si escribiera diferentes clases en Java.

Como he estado aprendiendo más sobre jQuery, me he dado cuenta de que la notación $.fn.foo = function() { ... }; realmente está agregando esta función foo al prototipo de todos los objetos jQuery. ¿Esto es algo que debería estar haciendo? ¿Estoy haciendo mal uso de jQuery de alguna manera?

Agradecería sugerencias sobre cómo mejorar mi enfoque de OOP en JavaScript y me gustaría ver referencias a fuentes/tutoriales/artículos/etc ... que discuten este tema. Por favor, siéntase libre de enviar comentarios, incluso si se ha seleccionado una respuesta. Estoy buscando su consejo ... esta es la razón por la que publiqué :)

** Nota: No estoy desarrollando un plugin jQuery. Estoy desarrollando una aplicación web y haciendo uso de jQuery.

+0

eche un vistazo a require.js para manejar su carga de archivos y dependencias para proyectos de gran tamaño. – Raynos

+0

@Raynos ... definitivamente echaremos un vistazo. es similar a http://headjs.com/ – Hristo

Respuesta

3

Diría que la primera forma en que está creando métodos es un uso indebido de jQuery. La sintaxis jQuery.fn.foo generalmente se reserva para las funciones que actúan sobre un elemento DOM pero las está utilizando como funciones estáticas, utilizando un objeto jQuery vacío.

Si desea crear funciones estáticas y en el espacio de nombres de jQuery, que puede hacer:

jQuery.foo = function(){}; 

luego llamarlo a través de:

jQuery.foo(); 

en lugar de:

jQuery.fn.foo = function(){}; 

cuales le permite hacer:

jQuery('#someElementId').foo(); 

En términos de OOP. hay muchos enfoques diferentes (patrón de módulo, prototipo, fábrica ...). La forma general me acerco a ella, es crear una clase como una función estática, entonces lo alega, con la palabra clave new

(function($){ 
    var undefined; 

    $.ClassName = function(options){ 
     var self = this; 
     var cfg = $.extend(true, {}, this.defaults, options); 

     // ******************** 
     // start:private 
     // ******************** 
     function _init(){ 

     }; 

     // ******************** 
     // start:public 
     // ******************** 
     this.methodName = function(){ 

     }; 

     _init(); 
    }; 

    $.ClassName.prototype.defaults = {}; 
})(jQuery); 

En cuanto a la reutilización de funcionalidad, hay un umbral tras el cual el desacoplamiento es más perjudicial que cualquier otra cosa. Asegúrese de mantener el equilibrio correcto de modularidad y organización.

+0

@alex ... ¡esto se ve bien, gracias! ¿Qué diferencia a lo que escribió de la idea de "espacio de nombres" que sugieren otros usuarios? – Hristo

+0

@Hristo Bueno, en realidad solo lo estoy poniendo en el espacio de nombres jQuery. La mayoría de las personas aquí están desaconsejando, así que mi código puede cambiarse fácilmente para que sea YOURNAMESPACE.ClassName = function() {} –

+0

@alex ... ohhh ok Entiendo. – Hristo

1

Si está desarrollando un complemento, generalmente es mejor evitar contaminar tanto los espacios de nombres jQuery como los prototipos globales tanto como sea posible.

Eche un vistazo a this documentation on jQuery's website, que ofrece una excelente explicación de cómo proporcionar acceso a una variedad de funciones reutilizables, mientras que solo reclama un único nombre en el objeto jQuery.

Otro método que he visto utilizado es proporcionar una única función de inicio para su complemento en el espacio de nombres de jQuery, y luego hacer un nombre adicional adicional disponible en el espacio de nombres Global, que proporciona un acceso más directo a la función/miembros, etc. El Galleria plug-in es un excelente ejemplo de cómo hacerlo bien. Examine su documentación y la forma en que configuran la estructura del complemento.

EDITAR

después de ver que son no hacer un plug-in: Muchas de las cosas que dije todavía se aplican al desarrollo general de jQuery (y realmente, para el desarrollo en general).

En su caso específico, dado que no está haciendo uso de los selectores de jQuery al hacer sus llamadas de función, estas funciones probablemente podrían adjuntarse fácilmente a un prototipo de su propia creación, que podría colocarse en el espacio de nombres global .

En cuanto a los espacios de nombre va, echar un vistazo a la respuesta aceptada sobre esta cuestión para un ejemplo de cómo hacerlo correctamente: How do I declare a namespace in JavaScript?

Y aquí es un gran recurso para OO en JavaScript.He utilizado este artículo cuando se trata de envolver mi cabeza alrededor del concepto: http://mckoss.com/jscript/object.htm

+0

@Ender ... 1. Me encanta tu nombre :) 2. Estoy ** no ** desarrollando un plugin. – Hristo

+0

@Ender ... gracias por el "Editar". Esa es la dirección en la que quiero dirigir. Ahora, he visto esta referencia al "espacio de nombres" dos veces ... ¿qué es eso?¿Cómo/dónde podría obtener más información sobre cómo crear mi propio espacio de nombres? – Hristo

+0

Acabo de agregar una referencia a otra pregunta de SO que * con suerte * responderá a esa pregunta :) – Ender

4

En referencia a hacer OO en Javascript debe ver Douglas Crockford's Advanced Javascript lessons

+0

@mlaw ... De hecho, estoy empezando a leer su libro "JavaScript - The Good Parts". Definitivamente voy a ver las lecciones. ¡Gracias! – Hristo

+0

Los videos son mucho más informativos que el libro. Aunque incluiré la referencia obligatoria de otro libro: JavaScript: The Definitive Guide (http://www.amazon.com/JavaScript-Definitive-Guide-David-Flanagan/dp/0596101996/ref=sr_1_2?ie=UTF8&qid= 1301429052 & sr = 8-2). –

0

Parece que estás escribiendo todo el código como plug-ins jQuery? Yo no haría eso. Crea tu propio espacio de nombres.

¿Cuál es el objetivo de poner todo en diferentes archivos? A menos que sean scripts que se utilizarán para páginas específicas, eso hace que sea más difícil administrar las cosas. Todos estos parecen funciones generales de la biblioteca. A menos que creas que querrás cargar algunos en una página, pero no todos, y luego colocarlos todos en un solo archivo.

La programación orientada a objetos no significa fragmentar cosas entre archivos. Eso es solo organización, debe dividir las cosas en diferentes archivos cuando no necesita todos los contenidos en alguna página.

+0

@jamietre ... hmm ... ¡eso tiene mucho sentido! No estoy tratando de escribir un complemento así que veo dónde está mi error. La razón por la que distribuyo las cosas entre los archivos es para poder agrupar la funcionalidad específica y ubicarla fácilmente, de modo que no tenga que desplazarme por un archivo gigante. ¿Qué quiere decir con "crear su propio espacio de nombres"? ¿Puedes proporcionar una explicación/sources/links/etc ...? – Hristo

6

Si no es un plugin de jQuery, me gustaría escribir algo como esto:

var app = { 
     init: function(){ 
     app.SetUpElements(); 
     }, 
     SetUpElements: function() { 
     return 'something'; 
     }, 
     etc: function() { 

     } 
    }; 
    $(document).ready(app.init); 
+0

@minibikini ... ¿qué representa la variable 'app'? – Hristo

+0

Esto es lo que @jamietre significa "configurar su propio espacio de nombres". 'app' es su objeto global con espacios de nombre que contendrá sus funciones y propiedades agrupadas. 'app' debe ser un nombre de aplicación muy único ya que es su objeto global primario. – mVChr

+0

@mVChr ... increíble, gracias! – Hristo

0

Como la mayoría ya han mencionado, a menos que explícitamente se está creando un plugin pública, no utilizan las funciones personalizadas jQuery. En su lugar, crea tu propio espacio de nombres usando notación de objeto directa, o algo más robusto como el Module Pattern. Si quieres volverte loco, puedes usar una API en la parte superior de una API para obtener un patrón OO más clásico usando Dean Edward's Base. El objetivo final es extraer sus requisitos funcionales y de diseño de la API de jQuery. De esa forma, si alguna vez necesitara transferir algo a Mootools o Prototype sería mucho más simple de lograr.

+0

@ hal10001 ... ¿puede proporcionar más información sobre cómo crear un espacio de nombres? Esta es la primera vez que escucho este término:/ – Hristo