1

Estoy desarrollando lo siguiente:

  • Primero, generé un array

  • Luego, hice una función que hace un shuffle de los valores dentro del array

  • Mezclé los valores del array

  • Mostré en diferentes variables los valores del array

Básicamente hice esto para obtener 6 valores aleatorios dentro de un rango determinado sin que se pudieran repetir.

El asunto es que quiero modularizar el script y no sé si conviene, ya que no puedo usar las variables con los índices del array porque quiero usar 4 valores de los 6 que tengo.

El código:

var autos = [1, 2, 3, 4, 5, 6];         
shuffleArray(autos);        

var valor1 = autos[0];
var valor2 = autos[1];
var valor3 = autos[2];
var valor4 = autos[3];

¿Cómo puedo modularizar eso y poder utilizar las variables valor como variable global?

2 Answers2

1

Primero veamos como podemos exponer nuestras variables cuando su alcance no es global, en el objeto window:

(function(window) {

  "use strict";

  var autos = [1, 2, 3, 4, 5, 6];

  //shuffleArray(autos);

  window.valor1 = autos[0];
  window.valor2 = autos[1];
  window.valor3 = autos[2];
  window.valor4 = autos[3];

})(window);

console.log(valor1, valor2, valor3, valor4);
// 1 2 3 4

Despues veamos como podemos modularizar:

(function() {

  var ModuloAutos = function() {

    "use strict";

    var modulo = {},
      autos = [1, 2, 3, 4, 5, 6];

    //shuffleArray(autos);

    modulo.valor1 = autos[0];
    modulo.valor2 = autos[1];
    modulo.valor3 = autos[2];
    modulo.valor4 = autos[3];

    return modulo;

  };

  var misAutos = new ModuloAutos();

  console.log(misAutos.valor1, misAutos.valor2, misAutos.valor3, misAutos.valor4);
  // 1 2 3 4

})();

Ya que sabemos como exponer una variable en el objeto window y como modularizar, podemos exponer una instancia de nuestro array:

(function(window) {

  var ModuloAutos = function() {

    "use strict";

    var modulo = {},
      autos = [1, 2, 3, 4, 5, 6];

    //shuffleArray(autos);

    modulo.valor1 = autos[0];
    modulo.valor2 = autos[1];
    modulo.valor3 = autos[2];
    modulo.valor4 = autos[3];

    return modulo;

  };

  window.autos = new ModuloAutos();

})(window);


console.log(autos.valor1, autos.valor2, autos.valor3, autos.valor4);
// 1 2 3 4
Ricky
  • 491
  • 3
  • 9
  • 1
    No si están en local scope, si gustas trata de acceder a la variable `ModuloAutos` fuera del IIFE. – Ricky May 01 '17 at 19:57
1

¿Cómo puedo modularizar eso y poder utilizar las variables valor como variable global?

La modularización siempre ha sido posible en el JavaScript moderno. Hay varias técnicas que puedes utilizar para este objetivo y que ciertamente son mejores que usar variables globales. En lo posible, no uses variables globales, tiene muchas contras y pocos pros. En este enlace puedes ver muy buenas respuestas al respecto.

Algunas estrategias son:

  • Namespaces y Module pattern
  • CommonJS, AMD, UMD, etc.
  • ES6 modules

Namespaces y module pattern

Un namespace o espacio de nombres, se refiere a un ente con un contexto propio y que guarda dentro distintos valores. Si has programado en C# entonces entenderás con exactitud qué es un namespace.

Por otro lado, el module pattern o patrón módulo, como su propio nombre lo indica, es un patrón de diseño creado para permitir la organización del código en módulos que, hablando en JavaScript, corresponde parcialmente a un namespace.

Este patrón se representa de la siguiente manera en JavaScript:

var modulo = (() => {
  const name = 'Hola Gustavo';
  
  return {
    greet() {
      return name;
    }
  }
})();

// en otro archivo
console.log(modulo.greet());

Es realmente sencillo usar este patrón. Solo necesitas meter las variables y métodos en una IIFE y estarán disponibles en el módulo/namespace. Si me dices, ¿qué tiene de especial contra guardar un objeto literal en window? La respuesta es que tienes un mayor control de lo que ocurre dentro de dicho módulo. Por ejemplo, puedes tener variables privadas, métodos privados/públicos, y todo estará dentro de dicho contexto, lo que no ocurre si usas un objeto literal.

CommonJS, AMD, UMD, RequireJS, etc.

Para no extender la respuesta, voy a tratar solo de CommonJS. CommonJS es una especificación que te permite programar en módulos y exportar, tanto valores individuales como un "todo", es decir, exportar todo el contenido del módulo:

// archivo A.js
module.exports = {
  const privada = 'valor';

  const metodo = function () {
    // hacer algo
  }
}

// Archivo B.js
const moduleA = require('B');

moduleA.metodo();

Esta especificación está implementada en Node.js de forma nativa.

ES6

ECMAScript 6 trajo una novedad que se venía pidiendo a gritos: módulos nativos. Estos llegaron y de inmediato significaron una mejora enorme en la forma en que escribes JavaScript. ES6 modules es una especificación con una sintaxis natural, por ejemplo, para exportar un módulo:

// archivo A.js
export const propiedad = 123;
export default function hacerAlgo() { ... }

Y para importar:

// archivo B.js
import hacerAlgo, { propiedad } from 'A';

Si bien ES6 modules aún no ha sido implementado en los navegadores (salvo por Safari Tech Preview), puedes usar esta especificación y todas las de ES6 en adelante mediante Babel.

gugadev
  • 18,776
  • 1
  • 24
  • 49