¿Cuál es la mejor forma de definir una función en javascript?

Quisiera saber cual es la mejor forma de definir una función en js, en mis años de desarrollo web, he visto muchas forma de hacerlo pero no se bien cual es digamos la más profesional y la mejor cuanto a el tiempo de carga de una web.

Respuesta
5

Hola masterpage, buena pregunta.

Javascript, al ser un lenguaje interpretado y no compilado, es siempre motivo de disputa en cuanto a patrones de diseño se habla ya que admite casi cualquier cosa.

Digamos que podríamos utilizar el dicho español de "cada maestrillo tiene su librillo" en este aspecto aunque, bien es verdad, que hay ciertos patrones que deberíamos respetar siempre para evitar conflictos con otros ficheros, permitir la reutilización y que afecten lo menos posible la velocidad de carga de web.

Para ello suelo usar un patrón de diseño similar al que se usaría en la programación orientada a objetos que encapsule cada "clase" con sus respectivas funciones y así evitar conflictos.

Por ejemplo, imagínate que quieres agregar funcionalidad javascript a dos botones de "compartir en twitter" y "compartir en facebook".

En todos los ejemplos se supone que se está usando la librería jquery

La manera más chapucera de hacerlo sería poniendo los scripts en el mismo html:

//HTML
<button id="twitter">Compartir en twitter</button>
<button id="facebook">Compartir en facebook</button>
<script>
    var compartirEnTwitter = function() {
       // Función de compartir en twitter
    };
    var compartirEnFacebook = function() {
       // Función de compartir en facebook
    };
    $("#twitter").on("click",function(){
      compartirEnTwitter();
    });
    $("#facebook").on("click",function(){
        compartirEnFacebook();
    });
</script>
//RESTO DEL HTML

Los problemas de este ejemplo son claros: no podemos reutilizar el código (si queremos compartir otra página tenemos que copiar y pegar en el nuevo html), lo que se descarga el usuario pesa más por lo que ralentiza la carga de la página y si algún otro js declara una variable llamada como nuestra función esta se sobreescribirá y tendremos un conflicto (sin hablar de que sería imposible hacer tests unitarios o herencia de ningún tipo aunque es ya algo más avanzado).

La primera mejora sería hacer un fichero aparte (para que solo se descargue la funcionalidad la primera vez y se pueda usar en varias páginas) pero seguiríamos con el problema del posible conflicto con dicha funcionalidad además de que para que nuestros botones funcionen tendrían obligatoriamente que tener el id "twitter" y "facebook" y solo se ejecuta en el click (¿y si ahora queremos que se comparta al hacer un submit?) Así que aplicamos el patrón de diseño para que nuestros métodos estén encapsuladas en una "clase":

//Creamos los "namespaces" para evitar tener conflicto de nombre con otros ficheros externos
var miproyecto = miproyecto || {};
//Creamos la "clase" aplicando el patron "closure" para evitar exponer métodos y variables que no queramos
miproyecto.redesSociales = (function() {
   // Creamos el objeto que vamos a "exponer" publicamente que, en nuestro ejemplo, son los dos métodos de compartir
   var publico = {};
   //Creamos los métodos privados de compartir
   var compartirEnTwitter = function() {};
   var compartirEnFacebook = function() {};
   //Creamos una enumeración para exponer publicamente y reutilizar el código que queramos de las funciones de compartir
   publico.tipo = {
      Twitter : 1,
      Facebook: 2
   };
   //Creamos el método público y genérico para compartir (gracias a esto y al enumerado añadir nuevas redes sociales a las que compartir será mucho más fácil)
   public.compartir = function(tipo) {
     switch(tipo) {
       case publico.tipo.Twitter:
         compartirEnTwitter();
         break;
       case publico.tipo.Facebook:
         compartirEnFacebook();
         break;
     }
   }
//Devolvemos solo el objeto "publico" con sus propiedades y funciones
  return publico;
})();

Luego, para usarlo, podrías hacer de nuevo la "chapucilla" en el html pero sin problemas de conflictos con otros ficheros:

//HTML
<button id="twitter">Compartir en twitter</button>
<button id="facebook">Compartir en facebook</button>
<script>
    $("#twitter").on("click",function(){
      miproyecto.redesSociales.compartir(miproyecto.redesSociales.tipo.Twitter);
    });
    $("#facebook").on("click",function(){
      miproyecto.redesSociales.compartir(miproyecto.redesSociales.tipo.Facebook);
    });
</script>
//RESTO DEL HTML

Este ejemplo es muy mejorable pero quiero que entiendas por encima las ventajas de usar el patrón de clases frente a "dejar caer" el javascript sin más:

  • Dejan de existir los problemas de conflicto de nombres
    • Al estar dentro de un namespace y de una clase te olvidas de que haya otro por ahí con una función "compartir" que rompa todo tu flujo
  • Solo se expone las propiedades y métodos que necesitas, nada más
  • Es 100% reutilizable y flexible
    • Agrega el fichero "redesSociales.js" a otra página que tenga también botones de compartir y haz que en se comparta, por ejemplo, en el submit de un formulario (cambiando el evento on y el selector en el js de la página en concreto)
  • 1 solo fichero = se descarga solo 1 vez
    • Da igual lo que el usuario navegue, recargue la página incluso que cierre sesión. El js estará en su navegador hasta que expire o limpie sus datos temporales
  • El código se ejecuta solo cuando se necesita
    • No se hace síncronamente a la carga de la página 
  • Es heredable y testeable
  • Es compatible con otros patrones de diseño javascript más avanzados

Espero que te hayas podido hacer una idea de como queda una clase js y de sus ventajas. Como te decía al principio existen muchísimos patrones de diseño javascript así que, si tienes interés y controlas el inglés, te dejo un link con unos cuantos explicados más a fondo:

http://www.dofactory.com/javascript/design-patterns 

Tio este example esta super, pero no logro hacerlo funcionar, debe ser alguna coma o punto o algo le paso el code a ver si me ayuda para que dispare un simple alert;

https://www.mediafire.com/?00i36yicwn4szsf 

Es verdad, está mal (tampoco esperaba que se fuera a usar tal cual, je je).

En la línea 16, en la declaración del método "compartir" he puesto "public" en lugar de "publico" :)

1 respuesta más de otro experto

Respuesta
2

Y por experiencia en otros lenguajes de programación, lo primero es externalizar el JS siempre que se pueda.

Además de eso, intentar reducir al máximo las líneas de código, con ello, también va que si para una chorrada usamos jQuery en vez de JavaScript puro eso también ralentiza el código. (No solo por una librería más, sino por ejecutar sus funciones)

Por ejemplo hacer:

$("#prueba").html("Hola prueba")

Requiere mas procesamiento que

document.getElementById("prueba").innerHTML = "Hola prueba";

Ya que realmente la función de jQuery tiene en su interior ese javascript.

Además de eso, lo típico, tener seccionado todo siempre para no repetir código (las mayores funciones posibles) y cuantas menos iteraciones menos tarda.

No se si es esto lo que me preguntas o directamente como estructuras código.

Comentame y vamos hablando.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas