Google acaba de publicar una guía de estilos y convenciones para el lenguaje Javascript que viene a sumarse a otras alternativas disponibles.
Lo interesante de este proyecto es que, como casi todo lo que emprende Google, tiene una respuesta inmediata por parte de la comunidad de desarrolladores, lo que puede resultar interesante para que de una vez, comencemos a estandarizar nuestros desarrollos.
En esta línea y, tras revisar el documento, lo primero que me llama la atención es la flexibilidad de muchas de sus reglas. Por fin encuentro en una guía de estilos recomendaciones que parecen haber sido diseñadas por desarrolladores en lugar de teóricos. Y esto, en los tiempos que corren, es toda una novedad.
Veámos algunas de las reglas más interesantes que proponen los chicos de Google y que podemos comenzar a utilizar de inmediato:
Reglas de estructuras
– Se aprueba el uso del operador ternario. Esto resulta una novedad frente a la documentación clásica que siempre desaconseja esta práctica dada su dificultad de lectura. Personalmente, no encuentro difícil ni escribir ni leer esta estructura, por lo que aplaudo la decisión.
En lugar de:
if (val != 0) { return foo(); } else { return bar(); } |
Podemos escribir:
return val ? foo() : bar(); |
– Se apoya el uso de los operadores binarios «&&» y «||». Esto de nuevo viene a ser una novedad frente a los que defienden que resulta difícil de seguir un código que utiliza estructuras encadenadas con operadores binarios. Pero incluso se va más allá, ya que proponen utilizarlos para crear expresiones complejas o para ofrecer un valor por defecto a una variable respectivamente:
if (node) { if (node.kids) { if (node.kids[index]) { foo(node.kids[index]); } } } |
Puede ser escrito de la siguiente forma:
var kid = node && node.kids && node.kids[index]; if (kid) { foo(kid); } |
Es muy interesante en el ejemplo anterior la declaración de una variable fuera del propio condicional donde se construye la expresión a evaluar.
Por su parte, el uso del operador ‘||’ ya lo hemos visto varias veces en este blog:
function foo(opt_win) { var win; if (opt_win) { win = opt_win; } else { win = window; } // ... } |
Puede simplificarse en:
function foo(opt_win) { var win = opt_win || window; // ... } |
– Se recomienda usar join() para construir cadenas. Este criterio ya lo habíamos comentado en este blog alguna vez. La teoría que respalda la decisión es que en Internet Explorer, es mucho más rápido el método join() que la concatenación clásica. Yo, además, aporto que es mucho más limpia y elegante cuando se trata de cadenas de longitudes considerables.
function listHtml(items) { var html = []; for (var i = 0; i < items.length; ++i) { html[i] = itemHtml(items[i]); } return ' <div class="foo">' + html.join(', ') + '</div> '; } |
– Iteración a través de una lista de nodos. El equipo de ingenieros, propone un modelo de bucle diferente al clásico para recorrer una colección de objetos. Personalmente, la encuentro elegante y no le veo objeciones.
var paragraphs = document.getElementsByTagName('p'); for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) { doSomething(paragraph); } |
De este modo, recorremos un array asegurándonos de no tratar aquellos valores que pueden ser tratado como falsos (falsy values)
– En la definición de un bucle para recorrer un array, la longitud del mismo se declara fuera del bucle. Angus Croll ya nos había aportado este modelo que, personalmente, me cuesta un poco adoptar. La idea es declarar una variable que almacene el tamaño del array a recorrer fuera de la propia declaración del bucle.
En lugar de:
for( i = 0, l = arr.length; i < l; i++ ){ // ... } |
Escribimos lo siguiente:
var l = arr.length; for( i = 0; i < l; i++ ){ // ... } |
– Es correcto declarar variables en el mismo momento en que se requieren. Otra genial decisión. Uno de los aspectos que más critico de herramientas como JSLint es que me obligan a declarar todas las variables que voy a necesitar al principio de una función: el motivo de esto es evitar problemas derivados del hoisting pero a mi entender, desorganizan el código.
– En la creación de cadenas, siempre es preferible el uso de comillas simples (‘) a las dobles («). Esto resulta útil cuando la cadena se compone de elementos HTML cuyos atributos se encierran entre comillas dobles.
var foo = "<div class="bar"></div>" |
– Uso de paréntesis. No hay que usar paréntesis con los operadores unarios ( typeof, void, delete ) ni tras operadores como return, throw, case o new.
– eval() solo se utilizará para parsear JSON (RPC)
Conclusión
Google nos ofrece una guía de estilo interesante para aplicar al desarrollo de nuestros proyectos Javascript. Como toda guía, no es un dogma, sólo un conjunto de recomendaciones pero, dada la influencia de la compañía, es una buena oportunidad para estandarizar proyectos.
Hola,
para evitar el uso de eval, tambien se puede usar:
así es como jquery parsea JSON.
Claro, que sólo en caso que el browser no soporte JSON.parse()
Saludos
Gracias Juan Pablo;
tienes razón, John Resig justificaba el uso de new Function() en este hilo:
http://forum.jquery.com/topic/json-performance-comparison-of-eval-and-new-function
Realmente, no se gana nada en seguridad. Incluso eval() es mucho más rápido, pero con este método se evitaban errores en Safari 4.
Saludos!