¿Mejores prácticas de Javascript orientadas a objetos? [cerrado]

251

Me encuentro codificando un gran proyecto en Javascript. Recuerdo que el último fue toda una aventura porque el JS hacky se vuelve rápidamente ilegible y quiero que este código esté limpio.

Bueno, estoy usando objetos para construir una biblioteca, pero hay varias formas de definir cosas en JS, lo que implica importantes consecuencias en el alcance, la gestión de la memoria, el espacio de nombres, etc. EG:

  • utilizando var o no;
  • definir cosas en el archivo o en un (function(){...})() estilo jquery;
  • utilizando this o no;
  • usando function myname()omyname = function() ;
  • definir métodos en el cuerpo del objeto o usar "prototipo";
  • etc.

Entonces, ¿cuáles son realmente las mejores prácticas al codificar en OO en JS?

Explicaciones académicas realmente esperadas aquí. Los enlaces a los libros son bienvenidos, siempre que traten con calidad y solidez.

EDITAR:

Obtuve algunas lecturas, pero todavía estoy muy interesado en las respuestas a las preguntas anteriores y las mejores prácticas.

e-satis
fuente
2
Tal vez "orientado a objetos" en el título debería reemplazarse por "moderno".
viam0Zah
43
Hmmm, 79 votos a favor, 82 favoritos, 91 votos a favor en la respuesta ... sin embargo, esto se cerró como no constructivo ... ¿por qué?
Brett Rossier
1
Escribí una clase simple que porta características de C ++ OOP a javascript con una sintaxis simple y natural. Vea mi respuesta aquí: stackoverflow.com/a/18239463/1115652
14
Este tipo de pregunta siempre se cierra. Entiendo las razones de esto, pero como son preguntas importantes y siempre populares (y dado que siempre las encuentro cuando tengo una pregunta similar), me pregunto si alguien puede dirigirnos al lugar adecuado para hacerlas.
KP MacGregor
2
@BrettRossier ¿De qué sirve el poder si no lo manejas? SO es la demostración en vivo de cómo funciona un orden jerárquico democrático. Seguramente algunos psicólogos lo están investigando ...

Respuestas:

288

Usando `var` o no

Debe introducir cualquier variable con la vardeclaración, de lo contrario, llega al ámbito global.

Vale la pena mencionar que en modo estricto ( "use strict";) arroja asignaciones de variables no declaradasReferenceError .

En la actualidad, JavaScript no tiene un alcance de bloque. La escuela Crockford le enseña a poner declaraciones var al comienzo del cuerpo de la función , mientras que la Guía de estilo de Dojo dice que todas las variables deben declararse en el menor alcance posible . (La letdeclaración y la definición introducidas en JavaScript 1.7 no forman parte del estándar ECMAScript).

Es una buena práctica vincular las propiedades de los objetos utilizados regularmente a las variables locales, ya que es más rápido que buscar en toda la cadena de alcance. (Ver Optimización de JavaScript para obtener un rendimiento extremo y un bajo consumo de memoria ).

Definir cosas en el archivo, o en un `(function () {...}) ()`

Si no necesita alcanzar sus objetos fuera de su código, puede envolver todo el código en una expresión de función, se llama patrón de módulo. Tiene ventajas de rendimiento y también permite que su código se minimice y se oscurezca a un alto nivel. También puede asegurarse de que no contaminará el espacio de nombres global. Funciones de envoltura en JavaScript también le permiten agregar un comportamiento orientado a aspectos. Ben Cherry tiene un artículo en profundidad sobre el patrón de módulo .

Usando `this` o no

Si usa la herencia pseudo-clásica en JavaScript, difícilmente puede evitar usarla this. Es cuestión de gustos qué patrón de herencia utilizas. Para otros casos, consulte el artículo de Peter Michaux sobre widgets de JavaScript sin "esto" .

Usando `function myname ()` o `myname = function ();`

function myname()es una declaración de función y myname = function();es una expresión de función asignada a variable myname. La última forma indica que las funciones son objetos de primera clase, y puede hacer cualquier cosa con ellas, como con una variable. La única diferencia entre ellos es que todas las declaraciones de funciones se elevan a la parte superior del alcance, lo que puede ser importante en ciertos casos. De lo contrario son iguales. function foo()es una forma abreviada Se pueden encontrar más detalles sobre el izado en el artículo de alcance y elevación de JavaScript .

Definir métodos en el cuerpo del objeto o usar "prototipo"

Tu decides. JavaScript tiene cuatro patrones de creación de objetos: pseudoclásicos, prototípicos, funcionales y partes ( Crockford, 2008 ). Cada uno tiene sus pros y sus contras, vea Crockford en sus videoconferencias u obtenga su libro The Good Parts como Anon ya lo sugirió .

Marcos

Le sugiero que elija algunos marcos de JavaScript, estudie sus convenciones y estilo, y encuentre las prácticas y patrones que mejor se adapten a usted. Por ejemplo, el Dojo Toolkit proporciona un marco robusto para escribir código JavaScript orientado a objetos que incluso admite herencia múltiple.

Patrones

Por último, hay un blog dedicado a explorar patrones y antipatrones comunes de JavaScript . Consulte también la pregunta ¿Existen estándares de codificación para JavaScript? en desbordamiento de pila.

viam0Zah
fuente
1
"JavaScript tiene cuatro patrones de creación de objetos: pseudo-clásico, prototípico, funcional y partes" - Realmente agradecería un resumen de los pros y los contras aquí.
BadHorsie
2
"La letdeclaración y la definición introducidas en JavaScript 1.7 no forman parte del estándar ECMAScript". Ahora es parte de ES6.
Michał Perłakowski
13

Voy a escribir algunas cosas que leí o puse en la aplicación desde que hice esta pregunta. Por lo tanto, las personas que lo leen no se sentirán frustradas, ya que la mayoría de las respuestas son disfraces de RTMF (incluso si debo admitirlo, los libros sugeridos SON buenos).

Uso Var

Se supone que cualquier variable ya está declarada en el ámbito superior en JS. Entonces, cuando quiera una nueva variable, declare que evitará sorpresas negativas como manipular una variable global sin darse cuenta. Por lo tanto, use siempre la palabra clave var.

En una marca de objeto, var la variable privada. Si solo desea declarar una variable pública, usethis.my_var = my_value para hacerlo.

Declarando métodos

En JS, son numerosas formas de declarar métodos. Para un programador de OO, la forma más natural y eficiente es utilizar la siguiente sintaxis:

Dentro del cuerpo del objeto

this.methodName = function(param) {

/* bla */

};

Hay un inconveniente: las funciones internas no podrán acceder a "esto" debido al divertido alcance de JS. Douglas Crockford recomienda evitar esta limitación utilizando una variable local convencional llamada "eso". Entonces se convierte

function MyObject() {

    var that = this;

    this.myMethod = function() {

        jQuery.doSomethingCrazy(that.callbackMethod);

    };

};

No confíe en el final de línea automático

JS intenta agregar automáticamente ;al final de la línea si lo olvida. No confíe en este comportamiento, ya que obtendrá errores que son un desastre para depurar.

e-satis
fuente
8

Primero debe leer sobre la programación basada en prototipos para saber qué tipo de bestia está tratando y luego echar un vistazo a la guía de estilo de JavaScript en MDC y la página de JavaScript en MDC . También me parece mejor forzar la calidad del código con una herramienta, es decir. JavaScript Lint u otras variantes.

Las mejores prácticas con OO suenan más como si quisiera encontrar patrones que concentrarse en la calidad del código, así que mire la búsqueda de Google: patrones de JavaScript y patrones de jQuery .

Bleadof
fuente
5

Es posible que desee ver Secretos del JavaScript Ninja por John Resig (jQuery). "Este libro tiene la intención de tomar un desarrollador intermedio de JavaScript y darle el conocimiento que necesita para crear una biblioteca de JavaScript entre navegadores, desde cero".

El borrador está disponible a través del editor: http://www.manning.com/resig/

Douglas Crockford también tiene algunos buenos artículos de JavaScript en su página de inicio: http://www.crockford.com/

gregers
fuente
5

A menudo me siento como el único hombre aquí que usa MooTools para mi javascript.

Es sinónimo de M y O bject O riented Herramientas, mootools.

Realmente me gusta su opinión sobre OOP en javascript. También puede usar su implementación de clase junto con jquery, por lo que no tiene que deshacerse de jquery (aunque mootools lo hace todo igual de bien).

De todos modos, dale una buena lectura al primer enlace y mira lo que piensas, el segundo enlace es a los documentos de Mootools.

MooTools y herencia

Clases de MooTools

Ryan Florence
fuente
No creo que tratar de cambiar un idioma para que se ajuste a tu antiguo habito es algo bueno. Es como esta gente en C, usando # para reemplazar hace que parezca fortran, o de lo contrario. Creo que se debe tratar de aprender la forma en que funciona el lenguaje (y su mejor practicesà, y usarlo de la manera que no se perturbe demasiado, pero no cambiarlo, de verdad..
e-satis
2
Creo que el sistema de objetos MooTools es bastante elegante y realmente me ayuda a mantener mi código organizado / encapsulado.
awesomo