¿Cómo estructura JavaScript? La edición del patrón del módulo | Programar Plus

JavaScript es interesante porque no impone ninguna estructura en particular sobre usted. “Traiga su propia organización”, por así decirlo. A medida que escribo más y más JavaScript en sitios de aplicaciones web, esto se vuelve cada vez más interesante. La forma en que estructura su JavaScript es muy importante porque:

  1. Si se hace correctamente, hace que el código sea más fácil de entender para los demás y para usted mismo al revisar su propio código.
  2. Tener una estructura decidida ayuda a mantener limpio el código futuro y fomenta las mejores prácticas declaradas.
  3. Hace que su código sea comprobable.

Antes de continuar, déjeme saber que estoy lejos de ser un maestro de JavaScript. Hay muchas personas inteligentes en el mundo de JavaScript que han estado haciendo y hablando de esto durante más tiempo del que yo sabía qué era un div.

Este ha sido un tema en mi mente últimamente porque he estado escribiendo mucho más JavaScript para CodePen, que es muy pesado en JavaScript. Hemos estado usando el “Patrón de módulo” desde el principio y creo que nos ha servido bastante bien.

Luego publiqué este artículo sobre la creación del anuncio de Treehouse, y dentro de él también usé el Patrón de módulo para JavaScript allí. Louis Lazaris intervino en que así es como le ha gustado escribir JavaScript también últimamente, y comenzó una pequeña discusión. Louis siguió con un artículo que explica su patrón estructural preferido.

El concepto

Es más fácil comprender conceptos como este si hay un ejemplo para construir. Digamos que estamos creando un widget de noticias. Enumera algunos artículos de noticias y tiene un botón en el que puede cargar más artículos de noticias.

El módulo

Principios humildes:

var NewsWidget = {

};

Solo un objeto. Me gustan mis variables de JavaScript que comienzan con un carácter en minúscula, pero los módulos obtienen un primer carácter en mayúscula. Solo una convención que ayuda a la legibilidad del código.

Ajustes

Es probable que el widget de noticias tenga algunos números significativos asociados (por ejemplo, cuántos artículos contiene). Además, algunos elementos importantes (nodos DOM) a los que se deberá acceder con regularidad.

Habrá una serie de subfunciones de este módulo que hacen pequeñas cosas específicas. Muchos de ellos pueden necesitar acceso a estas configuraciones y elementos “almacenados en caché”. Por lo tanto, pondremos la configuración a disposición de cada uno de ellos.

var s,
NewsWidget = {

  settings: {
    numArticles: 5,
    articleList: $("#article-list")
  }

};

Llegaremos al acceso a la subfunción en un segundo.

Función de inicialización

Para “empezar” tendremos una se llame a la función. Esto será coherente en todos los módulos, por lo que sabrá exactamente dónde buscar cuando comience a leer el código y descubra qué sucede y cuándo.

var s,
NewsWidget = {

  settings: {
    numArticles: 5,
    articleList: $("#article-list"),
    moreButton: $("#more-button")
  },

  init: function() {
    // kick things off
    s = this.settings;
  }

};

Lo primero que el init la función que hará es establecer la variable s (que declaramos al mismo nivel que el Módulo) para ser un puntero a la configuración. Por donde s fue declarado, esto significa que todas las subfunciones del Módulo tendrán acceso a la configuración. Bonito.

Vinculación de acciones de IU

Alex Vasquez estableció una convención para nosotros en CodePen en la que tendríamos una función solo para vincular los eventos de la interfaz de usuario. Nunca escribes ningún código que “haga cosas” cuando enlazas, simplemente haces el enlace y luego llamas a otra subfunción con el nombre apropiado.

var s,
NewsWidget = {

  settings: {
    numArticles: 5,
    articleList: $("#article-list"),
    moreButton: $("#more-button")
  },

  init: function() {
    s = this.settings;
    this.bindUIActions();
  },

  bindUIActions: function() {
    s.moreButton.on("click", function() {
      NewsWidget.getMoreArticles(s.numArticles);
    });
  },

  getMoreArticles: function(numToGet) {
    // $.ajax or something
    // using numToGet as param
  }

};

Combinar archivos

Lo más probable es que el widget de noticias no sea el único JavaScript que tendrá en una página. Habrá muchos módulos que necesitará cargar. Quizás el widget de noticias esté en todas las páginas de su sitio, por lo que pertenece a un archivo global.js. Este archivo global.js finalmente será un montón de módulos concatenados, y luego una gran fiesta de inicio.

Hay todo tipo de formas de manejar este asunto de la concatenación. Podría ser una herramienta de desarrollo como CodeKit y su capacidad para agregar / anteponer. Podría ser un script de compilación elegante de Grunt.js.

En CodePen usamos Ruby on Rails y su canalización de activos. Entonces, para nosotros, el archivo global.js sería algo como:

//= require common/library.js

//= require module/news-widget.js
//= require module/some-other-widget.js

(function() {

  NewsWidget.init();

  SomeOtherModule.init();

})();

Eso es todo amigos

Creo que es una forma bastante satisfactoria de escribir JavaScript. Satisface los tres puntos que hice sobre la importancia de la estructura.

Con respecto al punto de prueba, sé que no se discutió mucho, pero estoy seguro de que puedes imaginar cómo tener funciones específicas más pequeñas en el cambio de tareas específicas es más fácil para escribir afirmaciones. Así es como se realizan la mayoría de las pruebas de JavaScript (por ejemplo, Jasmine). Por ejemplo, en una forma u otra de código: “Afirmo que cuando esta función obtiene este valor, ocurre otra cosa y es igual a algún otro valor”.

Esta es la punta del iceberg. Acabo de comenzar, pero Learning JavaScript Design Patterns (¡gratis para leer en línea!) Por Addy Osmani parece ir mucho más profundo en este agujero de conejo.