Ir al contenido principal

Punto y coma y buenas prácticas de escritura en JavaScript

Introducción

La programación no consiste solamente en escribir código que funcione; también se trata de escribirlo de manera que sea legible, mantenible y consistente. Al igual que en la escritura convencional tenemos reglas gramaticales y de estilo, en JavaScript existen convenciones que ayudan a que nuestro código sea más profesional y fácil de entender. Uno de los aspectos que genera más debates entre los desarrolladores es el uso del punto y coma (;) para finalizar las instrucciones. ¿Es necesario? ¿Cuándo debemos usarlo? Además del punto y coma, existen otras prácticas de escritura que pueden mejorar significativamente la calidad de nuestro código. En este artículo, exploraremos estas cuestiones para ayudarte a desarrollar un estilo de codificación claro y profesional desde el principio de tu aprendizaje.

Uso obligatorio vs. opcional del punto y coma

En JavaScript, el punto y coma (;) se utiliza para separar instrucciones. A diferencia de otros lenguajes como C, Java o PHP, donde el punto y coma es estrictamente obligatorio, JavaScript ofrece cierta flexibilidad en su uso.

¿Es obligatorio el punto y coma en JavaScript?

La respuesta corta es: no es estrictamente obligatorio en la mayoría de los casos, pero existen situaciones donde omitirlo puede causar problemas.

JavaScript incorpora un mecanismo llamado "Inserción Automática de Punto y Coma" (Automatic Semicolon Insertion o ASI) que, como su nombre indica, inserta automáticamente puntos y coma donde el intérprete considera que deberían estar.

// Estas dos formas son equivalentes para el intérprete
let nombre = "Ana"    // Sin punto y coma
let edad = 28;        // Con punto y coma

// JavaScript interpreta ambas como:
let nombre = "Ana";
let edad = 28;

Sin embargo, confiar completamente en ASI puede llevarnos a errores sutiles y difíciles de detectar.

Casos donde el punto y coma es necesario

Existen situaciones específicas donde omitir el punto y coma puede causar comportamientos inesperados:

1. Cuando una línea comienza con [ o (
// Sin punto y coma - PROBLEMÁTICO
let a = 3
(function() {
    console.log("Esto se ejecuta inmediatamente")
})()

// JavaScript lo interpreta como:
let a = 3(function() {
    console.log("Esto se ejecuta inmediatamente")
})()
// ¡Error! Intenta llamar a 3 como si fuera una función

La solución es añadir el punto y coma:

// Con punto y coma - CORRECTO
let a = 3;
(function() {
    console.log("Esto se ejecuta inmediatamente")
})()
2. Al comenzar una línea con template literals (`)
// Sin punto y coma - PROBLEMÁTICO
let nombre = "Ana"
`Hola ${nombre}`

// JavaScript podría interpretarlo como:
let nombre = "Ana"`Hola ${nombre}`
// Lo que causaría un error
3. Al usar return, break, continue, throw seguido de nueva línea
// Sin punto y coma - PROBLEMÁTICO
function obtenerValor() {
    return
        { valor: 42 }
}

// JavaScript lo interpreta como:
function obtenerValor() {
    return;
        { valor: 42 }
}
// La función siempre devuelve undefined
4. Al usar declaraciones de una sola línea sin llaves
// Sin punto y coma - POTENCIALMENTE PROBLEMÁTICO
if (condicion) accion1()
accion2()

// Dependiendo de cómo funcione ASI, podría interpretarse incorrectamente

Ventajas de usar punto y coma

  1. Claridad: Marca explícitamente dónde termina cada instrucción.
  2. Consistencia: Mantiene un estilo coherente en todo el código.
  3. Prevención de errores: Evita problemas potenciales con ASI.
  4. Compatibilidad: Algunos minificadores o herramientas pueden requerir punto y coma.
  5. Familiaridad: Si vienes de otros lenguajes, mantiene consistencia con ellos.

Ventajas de omitir el punto y coma

  1. Menos tecleo: Reduces la cantidad de caracteres que escribes.
  2. Estética: Algunos desarrolladores consideran que el código se ve más limpio.
  3. Modernidad: Frameworks como React y herramientas como StandardJS promueven este estilo.

Automatic Semicolon Insertion (ASI)

El mecanismo de ASI (Inserción Automática de Punto y Coma) es una característica del intérprete de JavaScript que intenta corregir la sintaxis cuando falta un punto y coma. Es importante entender cómo funciona para evitar sorpresas.

Reglas básicas de ASI

  1. Final de línea: Se inserta un punto y coma cuando hay un salto de línea y la siguiente línea no puede interpretarse como continuación de la actual.

    let a = 5
    let b = 10
    // Se convierte en:
    let a = 5;
    let b = 10;
    
  2. Antes de corchetes de cierre }: Se inserta un punto y coma antes del corchete de cierre de un bloque si es necesario.

    function ejemplo() { return 42 }
    // Se convierte en:
    function ejemplo() { return 42; }
    
  3. Final de archivo: Se inserta un punto y coma al final del programa si es necesario.

  4. Después de ciertas palabras clave: Se inserta un punto y coma después de return, break, continue, throw si hay un salto de línea.

    return
    42
    // Se convierte en:
    return;
    42;
    // Lo que probablemente no es lo que esperabas
    

Casos problemáticos con ASI

La inserción automática puede llevar a resultados inesperados:

// Ejemplo 1: Return seguido de nueva línea
function obtenerObjeto() {
    return
    {
        valor: 42
    }
}
console.log(obtenerObjeto()); // Devuelve undefined, no el objeto

// Ejemplo 2: Expresión de función inmediatamente invocada
let a = 5
(function() {
    console.log(a)
})()
// Error: intenta interpretar 5 como una función

// Ejemplo 3: Operador unario al inicio de línea
let x = 10
let y = 20
++x
y = x + y
// Funciona, pero podría ser confuso

Buenas prácticas con respecto a ASI

Si decides no usar punto y coma, ten en cuenta estas reglas:

  1. Nunca comiences una línea con (, [, ` o + sin poner un punto y coma antes.
  2. Si usas return, break, continue o throw con un valor, ponlo en la misma línea.
  3. Sé consistente en todo tu código.
  4. Considera usar una herramienta de linting como ESLint para detectar problemas potenciales.
// Forma segura de omitir punto y coma
let a = 5
let b = 10

// Si necesitas comenzar con paréntesis, usa un punto y coma antes o un operador
;(function() {
    // código
})()

// O usa el operador de agrupación lógico
let c = a + b
&& (function() {
    // código
})()

Convenciones de estilo de código

Más allá del punto y coma, existen otras convenciones que mejoran la calidad y legibilidad de tu código JavaScript.

Indentación

La indentación (sangría) ayuda a visualizar la estructura jerárquica del código:

// Indentación con 2 espacios
function calcularTotal(productos) {
  let total = 0;
  for (let i = 0; i < productos.length; i++) {
    let producto = productos[i];
    total += producto.precio * producto.cantidad;
    if (producto.tieneDescuento) {
      total -= producto.descuento;
    }
  }
  return total;
}

// Indentación con 4 espacios
function calcularTotal(productos) {
    let total = 0;
    for (let i = 0; i < productos.length; i++) {
        let producto = productos[i];
        total += producto.precio * producto.cantidad;
        if (producto.tieneDescuento) {
            total -= producto.descuento;
        }
    }
    return total;
}

Lo más importante es ser consistente en todo tu código. Las convenciones más comunes son:

  • 2 espacios (preferido en muchos proyectos JavaScript modernos)
  • 4 espacios
  • Tabulaciones (menos común hoy en día)

Espaciado

El uso adecuado de espacios mejora la legibilidad:

// Espaciado recomendado
let resultado = (a + b) * c;
if (condicion) {
    hacerAlgo();
}
function suma(a, b) {
    return a + b;
}

// Espaciado comprimido (menos legible)
let resultado=(a+b)*c;
if(condicion){
    hacerAlgo();
}
function suma(a,b){
    return a+b;
}

Algunas convenciones comunes:

  • Espacio después de palabras clave (if, for, function, etc.)
  • Espacio alrededor de operadores (=, +, -, etc.)
  • Espacio después de comas en listas de argumentos
  • No espacio entre el nombre de función y el paréntesis en llamadas a funciones

Longitud de línea

Es recomendable limitar la longitud de cada línea para mejorar la legibilidad:

// Línea demasiado larga
let mensajeCompleto = "Estimado " + usuario.nombre + ", le informamos que su pedido #" + pedido.id + " ha sido procesado correctamente y será enviado a " + usuario.direccion + " en las próximas 24 horas.";

// Mejor: dividir en múltiples líneas
let mensajeCompleto = "Estimado " + usuario.nombre + 
    ", le informamos que su pedido #" + pedido.id + 
    " ha sido procesado correctamente y será enviado a " + 
    usuario.direccion + " en las próximas 24 horas.";

// O mejor aún: usar template literals
let mensajeCompleto = `Estimado ${usuario.nombre}, 
le informamos que su pedido #${pedido.id} 
ha sido procesado correctamente y será enviado a 
${usuario.direccion} en las próximas 24 horas.`;

El límite recomendado suele estar entre 80-120 caracteres por línea.

Corchetes y llaves

Existen diferentes estilos para colocar las llaves:

// Estilo K&R (Kernighan and Ritchie) - Común en JavaScript
if (condicion) {
    // código
} else {
    // más código
}

// Estilo Allman - Menos común en JavaScript
if (condicion) 
{
    // código
} 
else 
{
    // más código
}

El estilo K&R (con la llave de apertura en la misma línea) es el más utilizado en JavaScript.

Nomenclatura de variables y funciones

La forma de nombrar variables y funciones afecta mucho a la legibilidad:

// camelCase para variables y funciones (recomendado en JS)
let nombreUsuario = "Ana";
function calcularPrecioTotal() { /* ... */ }

// PascalCase para clases y constructores
class Usuario { /* ... */ }
function ProductoVirtual() { /* ... */ }

// SCREAMING_SNAKE_CASE para constantes (valores que nunca cambian)
const PI = 3.14159;
const DIAS_SEMANA = 7;

// snake_case (menos común en JavaScript, más común en Python)
let nombre_usuario = "Ana";
function calcular_precio_total() { /* ... */ }

En JavaScript, la convención más extendida es:

  • camelCase para variables, funciones y propiedades de objetos
  • PascalCase para clases y constructores
  • UPPERCASE_WITH_UNDERSCORES para constantes reales (valores inmutables)

Comentarios

Como vimos en el artículo anterior, los comentarios también deben seguir convenciones:

// Comentario de una línea

/*
 * Comentario multilínea
 * con formato consistente
 */

/**
 * Comentario de documentación (JSDoc)
 * @param {string} nombre - Descripción del parámetro
 * @returns {boolean} Descripción del valor devuelto
 */

Guías de estilo populares

En el mundo de JavaScript existen varias guías de estilo ampliamente adoptadas que puedes seguir:

Airbnb JavaScript Style Guide

Una de las más populares y completas. Promueve prácticas modernas y está orientada a ES6+.

Características principales:

  • Usa punto y coma al final de las instrucciones
  • Prefiere const sobre let, y evita var
  • 2 espacios para indentación
  • Límite de 100 caracteres por línea
  • Promueve el uso de funciones flecha (=>) cuando es apropiado

Guía de estilo de Airbnb

Google JavaScript Style Guide

La guía de estilo de Google, usada en muchos proyectos grandes.

Características principales:

  • Usa punto y coma al final de las instrucciones
  • 2 espacios para indentación
  • Prefiere utilizar const y let sobre var
  • Comentarios JSDoc para documentación

Guía de estilo de Google

StandardJS

A diferencia de las anteriores, StandardJS promueve no utilizar punto y coma.

Características principales:

  • No usa punto y coma
  • 2 espacios para indentación
  • Strings con comillas simples
  • No hay reglas de longitud máxima de línea estrictas

Guía StandardJS

ESLint y sus configuraciones

ESLint es una herramienta que verifica el estilo de tu código JavaScript y puede configurarse para seguir cualquiera de estas guías.

// Instalación de ESLint con la configuración de Airbnb
// En la terminal:
// npm install eslint eslint-config-airbnb-base --save-dev

// Archivo .eslintrc.json
{
  "extends": "airbnb-base"
}

Herramientas para mantener consistencia en el código

Existen varias herramientas que te ayudarán a mantener un estilo consistente:

Linters

Los linters analizan tu código y señalan problemas potenciales, tanto de estilo como de posibles errores:

  • ESLint: El más popular y configurable
  • JSLint: Más estricto y con menos opciones de configuración
  • JSHint: Un punto intermedio entre los anteriores

Ejemplo de configuración básica de ESLint:

// .eslintrc.json
{
  "extends": "eslint:recommended",
  "rules": {
    "semi": ["error", "always"],
    "indent": ["error", 2],
    "quotes": ["error", "single"],
    "no-unused-vars": "warn"
  }
}

Formateadores de código

Los formateadores automatizan el formateo de tu código según reglas predefinidas:

  • Prettier: Muy popular y con opiniones fuertes sobre el formato
  • js-beautify: Una alternativa más configurable

Ejemplo de configuración de Prettier:

// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5",
  "tabWidth": 2,
  "printWidth": 100
}

EditorConfig

EditorConfig ayuda a mantener estilos consistentes entre diferentes editores:

# .editorconfig
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

Git hooks con Husky

Puedes configurar git hooks para asegurarte de que todo el código cumple con tus reglas antes de ser commiteado:

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.js": ["eslint --fix", "prettier --write", "git add"]
  }
}

Ejemplos prácticos de estilos de código

Veamos un ejemplo de cómo el mismo código puede escribirse siguiendo diferentes convenciones:

Con punto y coma (estilo Airbnb)

// Estilo con punto y coma y 2 espacios de indentación (Airbnb)
const calcularImpuestos = (precio, porcentajeImpuesto = 21) => {
  if (typeof precio !== 'number') {
    throw new Error('El precio debe ser un número');
  }
  
  const impuesto = precio * (porcentajeImpuesto / 100);
  const total = precio + impuesto;
  
  return {
    precioBase: precio,
    impuesto: impuesto,
    total: total,
  };
};

const producto = {
  nombre: 'Laptop',
  precio: 1200,
};

const resultado = calcularImpuestos(producto.precio);
console.log(`Total a pagar: ${resultado.total}€`);

Sin punto y coma (estilo StandardJS)

// Estilo sin punto y coma y 2 espacios de indentación (StandardJS)
const calcularImpuestos = (precio, porcentajeImpuesto = 21) => {
  if (typeof precio !== 'number') {
    throw new Error('El precio debe ser un número')
  }
  
  const impuesto = precio * (porcentajeImpuesto / 100)
  const total = precio + impuesto
  
  return {
    precioBase: precio,
    impuesto,
    total
  }
}

const producto = {
  nombre: 'Laptop',
  precio: 1200
}

const resultado = calcularImpuestos(producto.precio)
console.log(`Total a pagar: ${resultado.total}€`)

Con 4 espacios de indentación

// Estilo con punto y coma y 4 espacios de indentación
const calcularImpuestos = (precio, porcentajeImpuesto = 21) => {
    if (typeof precio !== 'number') {
        throw new Error('El precio debe ser un número');
    }
    
    const impuesto = precio * (porcentajeImpuesto / 100);
    const total = precio + impuesto;
    
    return {
        precioBase: precio,
        impuesto: impuesto,
        total: total
    };
};

const producto = {
    nombre: 'Laptop',
    precio: 1200
};

const resultado = calcularImpuestos(producto.precio);
console.log(`Total a pagar: ${resultado.total}€`);

Elección de un estilo personal o de equipo

La elección de un estilo de código debe basarse en varios factores:

Factores a considerar

  1. Consistencia: Lo más importante es ser consistente en todo el código.
  2. Preferencias del equipo: En un entorno de equipo, es crucial seguir las convenciones acordadas.
  3. Estándares de la industria: Seguir guías populares facilita la incorporación de nuevos desarrolladores.
  4. Legibilidad: El objetivo final es que el código sea fácil de leer y entender.
  5. Herramientas: Considera qué herramientas utilizarás para mantener el estilo.

Recomendaciones para principiantes

Si estás comenzando en JavaScript, estas son algunas recomendaciones:

  1. Usa punto y coma: Aunque es opcional, usar punto y coma evita sorpresas para los principiantes.
  2. Sigue una guía existente: Airbnb o Google son buenas opciones para empezar.
  3. Usa herramientas de formateo: Configura ESLint y Prettier desde el principio.
  4. Sé consistente: Independientemente del estilo que elijas, aplícalo de manera uniforme.
  5. Mantén la mente abierta: A medida que adquieras experiencia, podrás formar opiniones más informadas sobre el estilo.

Documentar las decisiones de estilo

Es útil documentar las decisiones de estilo para tu proyecto:

/**
 * Guía de estilo para este proyecto:
 * - Usamos la guía de estilo de Airbnb como base
 * - 2 espacios para indentación
 * - Punto y coma al final de las instrucciones
 * - Comillas simples para strings
 * - No más de 100 caracteres por línea
 * - camelCase para variables y funciones
 * - PascalCase para clases y componentes
 */

Implementación práctica de estilo en un proyecto

Aquí tienes un ejemplo de cómo configurar un nuevo proyecto con reglas de estilo:

Paso 1: Inicializar el proyecto

mkdir mi-proyecto-js
cd mi-proyecto-js
npm init -y

Paso 2: Instalar las herramientas de estilo

npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-prettier

Paso 3: Configurar ESLint

Crear un archivo .eslintrc.json:

{
  "extends": [
    "eslint:recommended",
    "prettier"
  ],
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error",
    "semi": ["error", "always"],
    "quotes": ["error", "single"],
    "no-unused-vars": "warn"
  },
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  }
}

Paso 4: Configurar Prettier

Crear un archivo .prettierrc:

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "printWidth": 100,
  "trailingComma": "es5"
}

Paso 5: Configurar EditorConfig

Crear un archivo .editorconfig:

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 100
trim_trailing_whitespace = true

[*.{md,markdown}]
trim_trailing_whitespace = false

Paso 6: Añadir scripts útiles a package.json

"scripts": {
  "lint": "eslint .",
  "lint:fix": "eslint . --fix",
  "format": "prettier --write ."
}

Paso 7: Usar los scripts

# Verificar el estilo del código
npm run lint

# Corregir problemas automáticamente
npm run lint:fix

# Formatear todo el código
npm run format

Resumen

En este artículo hemos explorado uno de los aspectos más debatidos en JavaScript: el uso del punto y coma para finalizar instrucciones. Hemos visto que, aunque el punto y coma es técnicamente opcional en muchos casos gracias al mecanismo de ASI, existen situaciones donde omitirlo puede llevar a errores sutiles.

También hemos analizado otras prácticas de escritura que mejoran la legibilidad del código, como la indentación, el espaciado, la longitud de línea y las convenciones de nomenclatura. Hemos repasado algunas de las guías de estilo más populares en la comunidad JavaScript (Airbnb, Google, StandardJS) y las herramientas que nos ayudan a mantener la consistencia.

Lo más importante a recordar es que, independientemente del estilo que elijas, la consistencia es clave. Usar herramientas como ESLint, Prettier y EditorConfig te ayudará a mantener un código limpio y profesional.

En el próximo artículo, exploraremos otro aspecto fundamental de JavaScript: la sensibilidad a mayúsculas y minúsculas, y las convenciones de nomenclatura más utilizadas en el ecosistema JavaScript.