Módulo 01: Entorno de desarrollo
Objetivos del módulo
- Usar la consola de las DevTools del navegador para ejecutar código y depurar
- Conocer los métodos de
console:log,info,warn,error,table,group,time,diry otros - Preparar Visual Studio Code con las extensiones más útiles para JavaScript
- Incluir JavaScript en una página HTML de todas las formas posibles y entender
defer,asyncytype="module" - Instalar Node.js 24 LTS, usar su REPL y ejecutar ficheros
.jsy.mjs - Conocer las diferencias entre ejecutar JavaScript en el navegador y en Node.js
- Organizar la estructura de un primer proyecto
- Escribir tu primer programa en el navegador y en Node.js
- Depurar con breakpoints y con la instrucción
debugger - Entender el modo estricto y por qué los módulos ya lo activan
1. El navegador: tu primer entorno
No necesitas instalar nada para empezar: cualquier navegador moderno trae un motor de JavaScript y unas herramientas para desarrolladores (las DevTools). En este curso usaremos sobre todo Chrome o Edge (que comparten herramientas casi idénticas) y Firefox, pero todo funciona igual en Safari.
1.1 Abrir las DevTools
| Navegador | Abrir DevTools | Ir directamente a la consola |
|---|---|---|
| Chrome / Edge (Windows, Linux) | F12 o Ctrl + Mayús + I | Ctrl + Mayús + J |
| Chrome / Edge (macOS) | Cmd + Option + I | Cmd + Option + J |
| Firefox (Windows, Linux) | F12 o Ctrl + Mayús + I | Ctrl + Mayús + K |
| Firefox (macOS) | Cmd + Option + I | Cmd + Option + K |
| Safari (macOS) | Primero activa Ajustes → Avanzado → Mostrar funciones para desarrolladores web | Cmd + Option + C |
También puedes hacer clic derecho sobre cualquier parte de una página y elegir Inspeccionar.
Las DevTools tienen varios paneles. Estos son los que más usarás:
| Panel (Chrome) | Panel (Firefox) | Para qué sirve |
|---|---|---|
| Elements | Inspector | Ver y editar el HTML y el CSS de la página en vivo |
| Console | Consola | Ver mensajes y errores, y ejecutar JavaScript |
| Sources | Depurador | Ver los ficheros JavaScript, poner breakpoints y depurar |
| Network | Red | Ver cada petición que hace la página (HTML, imágenes, datos…) |
| Application | Almacenamiento | Ver localStorage, cookies, caché… |
1.2 Ejecutar código en la consola
La consola es un REPL (Read-Eval-Print Loop): lee lo que escribes, lo evalúa, imprime el resultado y vuelve a esperar. Es perfecta para probar cosas rápidamente.
✏️ Ejercicio: Abre la consola en una pestaña en blanco (
about:blank) y escribe, pulsandoIntrodespués de cada línea:
2 + 3
'Hola' + ' ' + 'mundo'
Math.max(4, 17, 9)
new Date().getFullYear()
Verás que después de cada línea aparece el resultado. Algunos trucos de la consola:
| Acción | Cómo |
|---|---|
| Ejecutar | Intro |
| Escribir varias líneas sin ejecutar | Mayús + Intro |
| Recuperar instrucciones anteriores | Flechas ↑ y ↓ |
| Autocompletar | Tab o → cuando aparece la sugerencia |
| Limpiar la consola | Ctrl + L o escribir clear() |
| Último elemento seleccionado en Elements | $0 |
⚠️ Importante: La primera vez que intentes pegar código en la consola de Chrome, te pedirá que escribas
allow pasting(o su equivalente en español). Es una protección contra estafas: algunos timadores piden a sus víctimas que peguen código en la consola para robarles la sesión. Nunca pegues en la consola código que te envíe un desconocido.
💡 Consejo: Lo que escribes en la consola se pierde al recargar la página. Para trozos de código más largos, en Chrome tienes Sources → Snippets: pequeños scripts que se guardan en el navegador y que puedes ejecutar con
Ctrl + Intro.
1.3 El objeto console
console es un objeto con muchos métodos para mostrar información. Aunque no forma parte de ECMAScript (es una API del entorno), está en todos los navegadores y en Node.js.
Mensajes básicos: log, info, warn, error
console.log('Mensaje normal');
console.info('Información'); // en Chrome se ve igual que log
console.warn('Cuidado: stock bajo'); // fondo amarillo y icono de advertencia
console.error('No se pudo guardar'); // fondo rojo y se cuenta como error
// Puedes pasar varios valores separados por comas
const nombre = 'Ana';
const edad = 28;
console.log('Usuario:', nombre, 'Edad:', edad);
// Usuario: Ana Edad: 28
💡 Consejo: La consola permite filtrar por nivel (Errores, Advertencias, Información…). Usar
warnyerroren vez delogpara los problemas te permite encontrarlos rápido entre cientos de mensajes. En Node.js,console.erroryconsole.warnescriben en la salida de errores (stderr) yconsole.logen la salida normal (stdout).
console.table: datos en forma de tabla
const usuarios = [
{ nombre: 'Ana', edad: 28, ciudad: 'Madrid' },
{ nombre: 'Luis', edad: 34, ciudad: 'Sevilla' },
{ nombre: 'Marta', edad: 22, ciudad: 'Valencia' },
];
console.table(usuarios);
// Salida en Node.js (en el navegador se ve como una tabla con estilo):
// ┌─────────┬─────────┬──────┬────────────┐
// │ (index) │ nombre │ edad │ ciudad │
// ├─────────┼─────────┼──────┼────────────┤
// │ 0 │ 'Ana' │ 28 │ 'Madrid' │
// │ 1 │ 'Luis' │ 34 │ 'Sevilla' │
// │ 2 │ 'Marta' │ 22 │ 'Valencia' │
// └─────────┴─────────┴──────┴────────────┘
console.table(usuarios, ['nombre', 'ciudad']); // solo esas columnas
console.group: agrupar mensajes
console.group('Pedido 1042');
console.log('Cliente: Ana');
console.group('Productos');
console.log('Teclado x1');
console.log('Ratón x2');
console.groupEnd();
console.log('Total: 59,90 €');
console.groupEnd();
// Salida:
// Pedido 1042
// Cliente: Ana
// Productos
// Teclado x1
// Ratón x2
// Total: 59,90 €
En el navegador, cada grupo se puede plegar y desplegar. console.groupCollapsed() crea el grupo ya plegado.
console.time: medir cuánto tarda algo
console.time('bucle');
let suma = 0;
for (let i = 0; i < 1_000_000; i++) {
suma += i;
}
console.timeEnd('bucle');
// bucle: 6.555ms (el número variará en tu ordenador)
La etiqueta ('bucle') debe ser la misma en time y timeEnd. Con console.timeLog('bucle') puedes ver el tiempo parcial sin detener el cronómetro.
console.dir: inspeccionar objetos
const config = {
servidor: { host: 'localhost', puerto: 3000, opciones: { ssl: { activo: false } } },
};
console.log(config);
// En Node.js, a partir de cierta profundidad muestra [Object]:
// { servidor: { host: 'localhost', puerto: 3000, opciones: { ssl: [Object] } } }
console.dir(config, { depth: null }); // depth: null = sin límite (opción de Node.js)
En el navegador, console.dir muestra el objeto como un árbol desplegable de propiedades. Es especialmente útil con elementos de la página: console.log(document.body) muestra el HTML, mientras que console.dir(document.body) muestra el objeto JavaScript con todas sus propiedades.
Otros métodos útiles
console.count('clic'); // clic: 1
console.count('clic'); // clic: 2 (cuenta cuántas veces se llama)
console.assert(1 + 1 === 3, 'Las matemáticas han fallado');
// Assertion failed: Las matemáticas han fallado (solo si la condición es falsa)
console.log('Nombre: %s, edad: %d', 'Ana', 28); // sustituciones al estilo C
// Nombre: Ana, edad: 28
// Solo en el navegador: dar estilos CSS con %c
console.log('%c¡Hola!', 'color: white; background: purple; font-size: 20px; padding: 4px;');
| Método | Uso |
|---|---|
console.log() | Mensaje general |
console.info() | Información (nivel “info”) |
console.warn() | Advertencia |
console.error() | Error |
console.table() | Arrays y objetos como tabla |
console.group() / groupCollapsed() / groupEnd() | Agrupar mensajes |
console.time() / timeLog() / timeEnd() | Medir tiempos |
console.dir() | Inspeccionar las propiedades de un objeto |
console.count() | Contar llamadas |
console.assert() | Mostrar un error solo si una condición es falsa |
console.clear() | Limpiar la consola |
⚠️ Importante: Los
console.logson para desarrollar, no para producción. Antes de publicar una web, elimina los mensajes de depuración (ESLint puede avisarte de ellos, como verás en el módulo 21).
2. Visual Studio Code
La consola está bien para pruebas, pero los programas de verdad se escriben en ficheros con un editor de código. El más usado para JavaScript es Visual Studio Code (VS Code), gratuito y disponible para Windows, macOS y Linux. Descárgalo de code.visualstudio.com.
📘 Concepto: VS Code es un editor, no un entorno de ejecución: te ayuda a escribir código (colores, autocompletado, avisos de errores), pero para ejecutarlo necesitas un navegador o Node.js. Curiosamente, VS Code está hecho con JavaScript y TypeScript sobre Electron.
2.1 Extensiones recomendadas
Abre el panel de extensiones con Ctrl + Mayús + X y busca:
| Extensión | Identificador | Para qué sirve |
|---|---|---|
| ESLint (Microsoft) | dbaeumer.vscode-eslint | Analiza tu código y marca errores y malas prácticas mientras escribes |
| Prettier - Code formatter | esbenp.prettier-vscode | Formatea el código automáticamente (sangrías, comillas, espacios) |
| Live Server (Ritwick Dey) | ritwickdey.LiveServer | Sirve tu carpeta en un servidor local y recarga el navegador al guardar |
| Live Preview (Microsoft) | ms-vscode.live-server | Alternativa oficial a Live Server, con vista previa dentro del editor |
| Error Lens | usernamehw.errorlens | Muestra los errores en la misma línea, sin pasar el ratón |
| Paquete de idioma español | MS-CEINTL.vscode-language-pack-es | Interfaz de VS Code en español |
También puedes instalarlas desde la terminal:
code --install-extension dbaeumer.vscode-eslint
code --install-extension esbenp.prettier-vscode
code --install-extension ritwickdey.LiveServer
💡 Consejo: ESLint y Prettier funcionan mejor cuando el proyecto tiene su propia configuración (
eslint.config.js,.prettierrc). En el módulo 21 los configurarás a fondo. Por ahora basta con que estén instalados.
2.2 Ajustes útiles
Abre la configuración en formato JSON con Ctrl + Mayús + P → Preferences: Open User Settings (JSON) y añade:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2,
"files.autoSave": "onFocusChange",
"editor.bracketPairColorization.enabled": true
}
2.3 Atajos imprescindibles
| Atajo | Acción |
|---|---|
Ctrl + Mayús + P | Paleta de comandos (desde aquí se hace todo) |
Ctrl + P | Abrir un fichero por su nombre |
Ctrl + ñ (teclado español) o Ctrl + ` | Abrir/cerrar la terminal integrada |
Ctrl + / | Comentar/descomentar líneas |
Alt + ↑ / Alt + ↓ | Mover la línea actual |
Mayús + Alt + ↓ | Duplicar la línea |
Ctrl + D | Seleccionar la siguiente aparición de la palabra (multicursor) |
F2 | Renombrar una variable en todo el fichero |
Mayús + Alt + F | Formatear el documento |
! + Tab en un .html | Generar el esqueleto HTML5 (Emmet) |
3. JavaScript dentro de una página HTML
El navegador ejecuta JavaScript cuando encuentra una etiqueta <script> en el HTML. Hay varias formas de usarla.
3.1 Script en línea
El código va directamente entre <script> y </script>:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Script en línea</title>
</head>
<body>
<h1>Hola</h1>
<script>
console.log('Este código está dentro del HTML');
</script>
</body>
</html>
Útil para pruebas rápidas, pero no para proyectos: mezcla contenido y comportamiento, no se puede reutilizar en otras páginas y el navegador no lo puede guardar en caché por separado.
3.2 Script externo
El código va en un fichero .js aparte y se enlaza con el atributo src:
<script src="js/main.js"></script>
// js/main.js
console.log('Este código está en un fichero externo');
⚠️ Importante: Si una etiqueta
<script>tienesrc, el código que escribas dentro de ella se ignora. Usa una etiqueta para cada cosa.
3.3 La posición importa
El navegador lee el HTML de arriba abajo. Por defecto, cuando encuentra un <script> clásico se detiene, descarga el fichero, lo ejecuta y solo entonces continúa leyendo el HTML. Esto tiene dos consecuencias:
- Si el script está en el
<head>, la página se queda en blanco mientras se descarga y ejecuta. - Si el script intenta acceder a un elemento que aparece más abajo, ese elemento todavía no existe.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Error típico</title>
<script>
// ❌ El párrafo aún no existe: devuelve null
const parrafo = document.querySelector('#saludo');
console.log(parrafo); // null
</script>
</head>
<body>
<p id="saludo">Hola</p>
</body>
</html>
La solución antigua era poner los scripts justo antes de </body>. La solución moderna es usar defer o type="module" en el <head>.
3.4 Los atributos defer, async y type="module"
| Forma | ¿Bloquea el HTML mientras se descarga? | ¿Cuándo se ejecuta? | ¿Respeta el orden entre scripts? |
|---|---|---|---|
<script src> (clásico) | Sí | Nada más descargarse | Sí |
<script src defer> | No | Cuando el HTML se ha leído entero, antes del evento DOMContentLoaded | Sí |
<script src async> | No (se descarga en paralelo) | En cuanto termina de descargarse, interrumpiendo el análisis del HTML | No |
<script type="module"> | No | Como defer (diferido por defecto) | Sí |
<script type="module" async> | No | Como async | No |
Leyenda: ███ análisis del HTML ↓↓↓ descarga del script ▓▓▓ ejecución
Clásico: ███████|↓↓↓↓↓↓|▓▓▓|████████████
^ el análisis del HTML se detiene
defer: ████████████████████████████|▓▓▓
↓↓↓↓↓↓ (en paralelo) ^ se ejecuta al terminar el HTML
async: █████████████|▓▓▓|█████████████
↓↓↓↓↓↓↓↓↓ ^ se ejecuta en cuanto llega (interrumpe)
module: ████████████████████████████|▓▓▓
↓↓↓↓↓↓ (+ sus dependencias) ^ igual que defer
flowchart TD
A["¿El script necesita el HTML<br/>o depende de otros scripts?"] -->|Sí| B["type=module<br/>(o defer si no es módulo)"]
A -->|No: es independiente,<br/>p. ej. analítica| C["async"]
📘 Concepto: Un módulo (
type="module") es la forma moderna de escribir JavaScript: puede usarimportyexportpara dividir el código en ficheros, tiene su propio ámbito (sus variables no “contaminan” la página), se ejecuta siempre en modo estricto y se difiere automáticamente. Es lo que usaremos en todo el curso. Lo estudiarás a fondo en el módulo 13.
💡 Consejo: La receta profesional para casi todos los casos es:
<script type="module" src="js/main.js"></script>dentro del<head>. No bloquea la página, se ejecuta cuando el HTML ya está listo y te permite usarimport.
3.5 Los módulos necesitan un servidor
Si abres un HTML haciendo doble clic, la dirección empieza por file://. Los navegadores bloquean la carga de módulos externos desde file:// por motivos de seguridad (política CORS) y verás un error como este en la consola:
Access to script at 'file:///C:/.../js/main.js' from origin 'null' has been blocked by CORS policy
La solución es servir la carpeta con un servidor local:
- En VS Code: clic derecho sobre el
index.html→ Open with Live Server (o el botón Go Live de la barra inferior). Se abrirá en una dirección comohttp://127.0.0.1:5500. - Con Node.js instalado:
npx serveen la carpeta del proyecto (descarga y ejecuta un pequeño servidor).
3.6 Atributos menos usados
nomodule: el script solo se ejecuta en navegadores antiguos que no entienden módulos. Hoy apenas se usa.<noscript>: contenido que se muestra solo si JavaScript está desactivado.crossorigineintegrity: para cargar scripts de otros dominios (CDN) de forma segura. Los verás al usar bibliotecas externas.
4. Node.js 24 LTS
Node.js es un entorno para ejecutar JavaScript fuera del navegador, directamente en tu ordenador. Lo necesitarás para muchos ejemplos del curso y para las herramientas profesionales (npm, Vite, ESLint, Vitest).
4.1 Versiones: Current y LTS
📘 Concepto: LTS significa Long Term Support (soporte a largo plazo). Las versiones LTS reciben correcciones de errores y de seguridad durante años, por eso son las que se usan en empresas y en este curso.
| Versión | Estado (octubre de 2026) |
|---|---|
| Node.js 24 | Active LTS: la recomendada para este curso |
| Node.js 26 | Current; pasa a LTS el 28 de octubre de 2026 |
| Node.js 22 | Maintenance LTS: solo correcciones críticas |
Tradicionalmente salían dos versiones mayores al año y solo las pares llegaban a LTS. A partir de Node.js 27 el proyecto pasa a publicar una única versión mayor al año. Todo el código del curso funciona en Node.js 24 y posteriores.
4.2 Instalación en Windows
Opción A: instalador oficial (la más sencilla)
- Entra en nodejs.org y descarga el instalador LTS para Windows (
.msi). - Ejecútalo y acepta las opciones por defecto (incluye npm, el gestor de paquetes).
- Cierra y vuelve a abrir la terminal.
También puedes instalarlo con el gestor de paquetes de Windows:
winget install OpenJS.NodeJS.LTS
Opción B: un gestor de versiones (recomendada a medio plazo)
Un gestor de versiones te permite tener varias versiones de Node.js instaladas y cambiar entre ellas, algo muy habitual cuando trabajas en proyectos distintos.
Con nvm-windows:
winget install CoreyButler.NVMforWindows
# Cierra y abre la terminal, después:
nvm install 24
nvm use 24
nvm list # versiones instaladas
Con fnm (Fast Node Manager, multiplataforma):
winget install Schniz.fnm
# Añade esta línea a tu perfil de PowerShell (notepad $PROFILE) para activarlo:
# fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression
fnm install 24
fnm use 24
fnm default 24
4.3 Instalación en macOS y Linux
Puedes usar el instalador de nodejs.org, pero lo más habitual es nvm. Sigue las instrucciones de instalación de su repositorio oficial (github.com/nvm-sh/nvm) y después:
nvm install 24
nvm use 24
nvm alias default 24
⚠️ Importante: No mezcles métodos. Si instalas Node.js con el instalador oficial y además con un gestor de versiones, tendrás dos copias peleándose. Elige uno.
4.4 Comprobar la instalación
node -v
# v24.19.0 (o la versión 24.x que tengas)
npm -v
# 11.x.x
Si aparece “node no se reconoce como un comando”, cierra todas las terminales (y VS Code) y vuelve a abrirlas para que se actualice la variable PATH.
4.5 El REPL de Node.js
Igual que la consola del navegador, Node.js tiene un REPL. Escribe node sin argumentos:
PS C:\> node
Welcome to Node.js v24.19.0.
Type ".help" for more information.
> 2 + 3
5
> const nombre = 'Ana'
undefined
> `Hola, ${nombre}`
'Hola, Ana'
> _.length
9
> .exit
| Comando del REPL | Qué hace |
|---|---|
.help | Lista de comandos |
.editor | Modo editor para escribir varias líneas (termina con Ctrl + D) |
.exit o Ctrl + D | Salir (también Ctrl + C dos veces) |
_ | El resultado de la última expresión |
Tab | Autocompletar |
📘 Concepto: ¿Por qué aparece
undefineddespués deconst nombre = 'Ana'? Porque el REPL siempre muestra el valor de lo que ejecutas, y una declaración de variable no produce ningún valor. No es un error.
4.6 Ejecutar ficheros: .js y .mjs
Crea un fichero hola.mjs:
// hola.mjs
console.log('¡Hola desde Node.js!');
console.log(`Versión de Node: ${process.version}`);
Y ejecútalo desde la terminal, en la carpeta del fichero:
node hola.mjs
# ¡Hola desde Node.js!
# Versión de Node: v24.19.0
Node.js tiene dos sistemas de módulos: el moderno y estándar, ES Modules (import/export), y el antiguo propio de Node, CommonJS (require/module.exports). La extensión del fichero y el package.json deciden cuál se usa:
| Fichero | Se trata como |
|---|---|
.mjs | Siempre módulo ES |
.cjs | Siempre CommonJS |
.js con "type": "module" en el package.json | Módulo ES |
.js sin "type" | CommonJS… salvo que Node detecte sintaxis import/export, en cuyo caso lo reinterpreta como módulo ES (y puede mostrar un aviso) |
💡 Consejo: En este curso usaremos módulos ES. Para ejemplos sueltos, usa la extensión
.mjs. En proyectos, crea unpackage.jsoncon"type": "module"y usa.jsnormal (lo verás en la sección 6).
4.7 node --watch: reejecutar al guardar
Mientras programas, es pesado volver a escribir node fichero tras cada cambio. Con --watch, Node.js vigila el fichero y lo reejecuta automáticamente cada vez que guardas:
node --watch hola.mjs
Para salir, pulsa Ctrl + C.
4.8 Otras formas útiles de usar node
node -e "console.log(2 ** 10)" # ejecuta el código del texto: 1024
node -p "Math.PI.toFixed(4)" # ejecuta e imprime el resultado: 3.1416
node --run dev # ejecuta el script "dev" del package.json
5. Navegador frente a Node.js
El lenguaje es el mismo, pero el entorno cambia lo que puedes hacer:
| Característica | Navegador | Node.js |
|---|---|---|
| Objeto global | window (también globalThis) | globalThis (también global) |
| Página web (DOM) | Sí: document, elementos, eventos | No existe |
alert, prompt, confirm | Sí | No |
| Acceso a ficheros del disco | No (solo si el usuario elige uno) | Sí, con node:fs |
| Información del proceso | No | process (argumentos, variables de entorno…) |
| Peticiones de red | fetch | fetch (y módulos node:http, node:https) |
| Módulos | <script type="module">, import por URL | Módulos ES y CommonJS, import de paquetes npm |
Dónde sale console.log | Consola de DevTools | La terminal |
| Seguridad | Muy restringido (sandbox) | Acceso completo al sistema (con los permisos de tu usuario) |
// Este código funciona en ambos entornos
console.log(typeof globalThis); // object
// ¿Dónde estoy?
if (typeof window !== 'undefined') {
console.log('Estoy en un navegador');
} else if (typeof process !== 'undefined') {
console.log('Estoy en Node.js');
}
💡 Consejo:
globalThis(ES2020) es la forma estándar de acceder al objeto global en cualquier entorno. Si alguna vez necesitas el objeto global, usaglobalThisen lugar dewindowoglobal.
6. Estructura de un primer proyecto
Mantener el proyecto ordenado desde el principio es un hábito profesional. Crea una carpeta para tus prácticas del curso, por ejemplo C:\cursos\javascript\, y dentro una carpeta por proyecto.
6.1 Proyecto para el navegador
mi-primera-web/
├── index.html ← la página principal
├── css/
│ └── estilos.css ← el diseño
└── js/
└── main.js ← el comportamiento (punto de entrada)
6.2 Proyecto para Node.js
mi-primer-script/
├── package.json ← descripción del proyecto
└── src/
└── index.js ← punto de entrada
El package.json se crea con npm:
mkdir mi-primer-script
cd mi-primer-script
npm init -y # crea un package.json con valores por defecto
npm pkg set type=module # añade "type": "module"
{
"name": "mi-primer-script",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node src/index.js",
"dev": "node --watch src/index.js"
}
}
📘 Concepto: El
package.jsones el “carné de identidad” de un proyecto de JavaScript: nombre, versión, tipo de módulos, scripts que puedes lanzar (npm run devonode --run dev) y dependencias. Lo estudiarás a fondo en el módulo 20. El contenido que generanpm init -yincluye algunos campos más (description,license…); elscriptsde arriba lo añades tú.
6.3 Nombres de ficheros y carpetas
- Usa minúsculas y guiones:
lista-tareas.js, noLista Tareas.js. - Sin espacios, tildes ni eñes en nombres de ficheros: dan problemas en URLs y servidores.
- El fichero principal suele llamarse
main.jsoindex.js.
7. Tu primer programa
7.1 En el navegador
💻 Ejemplo: Una página que te saluda por tu nombre y te dice cuántos días faltan para fin de año.
<!-- mi-primera-web/index.html -->
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mi primer programa</title>
<link rel="stylesheet" href="css/estilos.css">
<script type="module" src="js/main.js"></script>
</head>
<body>
<h1 id="titulo">Cargando...</h1>
<p id="info"></p>
</body>
</html>
/* mi-primera-web/css/estilos.css */
body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 2rem auto;
padding: 0 1rem;
}
h1 {
color: rebeccapurple;
}
// mi-primera-web/js/main.js
const nombre = prompt('¿Cómo te llamas?') || 'desconocido';
const hoy = new Date();
const finDeAnio = new Date(hoy.getFullYear(), 11, 31); // los meses empiezan en 0: 11 = diciembre
const msPorDia = 1000 * 60 * 60 * 24;
const diasRestantes = Math.ceil((finDeAnio - hoy) / msPorDia);
document.querySelector('#titulo').textContent = `¡Hola, ${nombre}!`;
document.querySelector('#info').textContent = `Faltan ${diasRestantes} días para fin de año.`;
console.log('Programa ejecutado correctamente');
Ábrelo con Live Server y comprueba también la consola de las DevTools.
📘 Concepto: Fíjate en que el script está en el
<head>y aun así encuentra#titulo: como es un módulo, espera a que el HTML esté completo antes de ejecutarse.
7.2 En Node.js
💻 Ejemplo: Un programa que recibe tu nombre desde la línea de comandos.
// mi-primer-script/src/index.js
import os from 'node:os';
// process.argv contiene: [ruta de node, ruta del script, ...argumentos]
const nombre = process.argv[2] ?? 'desconocido';
console.log(`¡Hola, ${nombre}!`);
console.log(`Sistema operativo: ${os.platform()}`);
console.log(`Usuario: ${os.userInfo().username}`);
console.log(`Node.js ${process.version}`);
node src/index.js Ana
# ¡Hola, Ana!
# Sistema operativo: win32
# Usuario: Fran
# Node.js v24.19.0
✏️ Ejercicio: Ejecuta el programa sin argumento (
node src/index.js) y después connpm start. ¿Qué nombre aparece en cada caso?
8. Depuración básica
📘 Concepto: Depurar (debug) es encontrar y corregir errores. Llenar el código de
console.logfunciona, pero un depurador es mucho más potente: te permite detener el programa en una línea, ver el valor de todas las variables en ese momento y avanzar instrucción a instrucción.
8.1 Un programa con un error
// js/media.js
const notas = [7, 8.5, 6, 9];
function calcularMedia(lista) {
let suma = 0;
for (let i = 0; i <= lista.length; i++) { // ← aquí hay un error
suma += lista[i];
}
return suma / lista.length;
}
console.log('Media:', calcularMedia(notas)); // Media: NaN ¿Por qué?
NaN significa Not a Number: algo ha salido mal en la suma. Vamos a averiguarlo con el depurador.
8.2 Breakpoints en las DevTools
- Carga la página con el script y abre Sources (Chrome) o Depurador (Firefox).
- Busca el fichero
media.jsen el árbol de la izquierda (o pulsaCtrl + P). - Haz clic en el número de línea de
suma += lista[i];. Aparecerá una marca azul: es un breakpoint (punto de interrupción). - Recarga la página. La ejecución se detendrá en esa línea.
- Mira el panel Scope: verás
i,sumaylistacon sus valores actuales. - Pulsa Resume (
F8) varias veces y observa cómo cambianiysuma. Cuandoivale 4,lista[4]esundefined, y6 + ... + undefineddaNaN.
El error es la condición i <= lista.length: debería ser i < lista.length, porque los índices van de 0 a 3.
| Botón / atajo (Chrome) | Acción |
|---|---|
F8 Resume | Continuar hasta el siguiente breakpoint |
F10 Step over | Ejecutar la línea actual y pasar a la siguiente |
F11 Step into | Entrar dentro de la función que se llama en esta línea |
Mayús + F11 Step out | Terminar la función actual y volver a quien la llamó |
| Panel Scope | Variables visibles en ese punto |
| Panel Watch | Expresiones que quieres vigilar (por ejemplo, lista[i]) |
| Panel Call Stack | Cadena de funciones que han llevado hasta aquí |
💡 Consejo: Haz clic derecho sobre el número de línea para crear un breakpoint condicional (solo se detiene si se cumple una condición, por ejemplo
i === 4) o un logpoint (escribe un mensaje en la consola sin detenerse, como unconsole.logque no ensucia el código).
8.3 La instrucción debugger
También puedes poner un breakpoint desde el propio código:
function calcularMedia(lista) {
let suma = 0;
for (let i = 0; i <= lista.length; i++) {
debugger; // el programa se detiene aquí SI las DevTools están abiertas
suma += lista[i];
}
return suma / lista.length;
}
⚠️ Importante:
debuggersolo tiene efecto si hay un depurador conectado (por ejemplo, las DevTools abiertas). Si no, se ignora. Aun así, no lo dejes nunca en código publicado.
8.4 Depurar en Node.js y en VS Code
- VS Code: abre la paleta (
Ctrl + Mayús + P) → Debug: JavaScript Debug Terminal. Todo lo que ejecutes connodeen esa terminal se conecta al depurador de VS Code y se detiene en tus breakpoints (los pones haciendo clic a la izquierda del número de línea). - Chrome DevTools: ejecuta
node --inspect-brk src/index.js, abrechrome://inspecten Chrome y pulsa inspect. Tendrás las mismas herramientas que con una página web.
8.5 Leer un mensaje de error
Uncaught ReferenceError: nombr is not defined
at saludar (main.js:3:15)
at main.js:6:1
| Parte | Significado |
|---|---|
Uncaught | Nadie ha capturado el error (lo verás en el módulo 10) |
ReferenceError | El tipo de error: se usa algo que no existe |
nombr is not defined | La descripción: nombr no está definido (¿una errata de nombre?) |
at saludar (main.js:3:15) | Dónde: función saludar, fichero main.js, línea 3, columna 15 |
at main.js:6:1 | Quién llamó a esa función (la pila de llamadas) |
9. Modo estricto
9.1 ¿Qué es?
JavaScript nació siendo muy permisivo: muchos errores no producían ningún aviso y el programa seguía funcionando… mal. En ES5 (2009) se añadió el modo estricto (strict mode), una variante del lenguaje que convierte esos errores silenciosos en errores visibles y prohíbe algunas características peligrosas.
Se activa escribiendo la cadena 'use strict' (o "use strict") como primera instrucción de un fichero o de una función:
'use strict';
contador = 10; // ❌ ReferenceError: contador is not defined
Sin modo estricto, la línea anterior crea una variable global sin avisar, un error clásico cuando escribes mal el nombre de una variable.
9.2 Qué cambia
| Situación | Sin modo estricto | Con modo estricto |
|---|---|---|
| Asignar a una variable no declarada | Crea una variable global | ReferenceError |
| Asignar a una propiedad de solo lectura | Se ignora en silencio | TypeError |
Parámetros con nombre repetido function f(a, a) | Permitido | Error de sintaxis |
this en una función normal llamada sin objeto | El objeto global | undefined |
Números octales antiguos como 010 | Valen 8 | Error de sintaxis |
Instrucción with | Permitida | Error de sintaxis |
Palabras reservadas para el futuro (let, static, implements…) como nombres | Algunas permitidas | Error de sintaxis |
9.3 Los módulos ya son estrictos
⚠️ Importante: Todo el código de un módulo ES (
<script type="module">, ficheros.mjso.jscon"type": "module") y todo el cuerpo de una clase se ejecutan automáticamente en modo estricto. No necesitas escribir'use strict'.
// prueba.mjs (módulo: estricto automáticamente)
total = 5;
console.log(total);
PS C:\cursos> node prueba.mjs
file:///C:/cursos/prueba.mjs:2
total = 5;
^
ReferenceError: total is not defined
Como en este curso trabajamos siempre con módulos, siempre estarás en modo estricto. Es una ventaja: el lenguaje te avisa antes de tus errores.
💡 Consejo: Si alguna vez trabajas con scripts clásicos (sin
type="module") o con CommonJS, empieza cada fichero con'use strict';.
10. Ejercicios
Ejercicio 1: Explorador de la consola
Abre la consola de las DevTools en cualquier web y:
- Calcula cuántos segundos tiene un año (
365 * 24 * 60 * 60). - Escribe
document.titley comprueba que devuelve el título de la pestaña. - Ejecuta
document.body.style.background = 'yellow'y observa la página. Recárgala: ¿se mantiene el cambio? ¿Por qué?
Ejercicio 2: Informe en consola
Crea un fichero informe.mjs que, con los métodos de console, muestre:
- Un grupo “Alumnos” con una tabla (
console.table) de cuatro alumnos con nombre, edad y nota. - Una advertencia si algún alumno tiene una nota menor que 5 (puedes escribirla a mano por ahora).
- El tiempo que tarda en ejecutarse un bucle que suma los números del 1 al 10 millones (
console.time).
Ejecútalo con node --watch informe.mjs y modifica los datos para ver cómo se reejecuta.
Ejercicio 3: Las cuatro formas de cargar un script
Crea una página con cuatro scripts externos (a.js, b.js, c.js, d.js) en el <head>, cargados respectivamente de forma clásica, con defer, con async y con type="module". Cada uno debe hacer console.log de su nombre y de document.querySelector('p') (pon un párrafo en el <body>). Anota en qué orden aparecen los mensajes y cuál de ellos encuentra el párrafo. Explica el resultado con la tabla de la sección 3.4.
Ejercicio 4: Proyecto completo en el navegador
Crea el proyecto tarjeta-presentacion con la estructura de la sección 6.1. La página debe mostrar tu nombre, una frase y la fecha actual; el nombre y la fecha deben escribirse desde js/main.js (usa document.querySelector y textContent). Ábrelo con Live Server.
Ejercicio 5: Script de Node con argumentos
Crea un proyecto Node con package.json ("type": "module") y un src/index.js que reciba dos números por la línea de comandos y muestre su suma, resta, multiplicación y división. Pista: process.argv[2] es un texto; conviértelo con Number(process.argv[2]). Añade un script "calcular" al package.json y ejecútalo con npm run calcular -- 8 2.
Ejercicio 6: Caza el error con el depurador
Copia el programa de la sección 8.1 en una página, pon un breakpoint y sigue la ejecución paso a paso con F10. Añade lista[i] al panel Watch. Corrige el error y comprueba que la media es 7.625. Después repite el ejercicio en VS Code con la JavaScript Debug Terminal.
Ejercicio 7: Estricto o no estricto
Crea dos ficheros, suelto.cjs y modulo.mjs, ambos con el mismo contenido:
mensaje = 'Hola';
console.log(mensaje);
Ejecuta los dos con Node.js. ¿Qué ocurre en cada caso y por qué? Añade 'use strict'; al principio de suelto.cjs y vuelve a ejecutarlo.
Resumen
| Concepto | Sintaxis / herramienta |
|---|---|
| Abrir la consola | F12, Ctrl + Mayús + J (Chrome/Edge), Ctrl + Mayús + K (Firefox) |
| Mensajes | console.log(), info(), warn(), error() |
| Tablas y grupos | console.table(), console.group() / groupEnd() |
| Medir tiempo | console.time('x') / console.timeEnd('x') |
| Inspeccionar objetos | console.dir(obj) |
| Editor | VS Code + ESLint + Prettier + Live Server |
| Script externo | <script src="js/main.js"></script> |
| Diferido | <script src="..." defer></script> |
| Asíncrono | <script src="..." async></script> |
| Módulo (recomendado) | <script type="module" src="js/main.js"></script> |
| Comprobar Node.js | node -v, npm -v |
| REPL | node (salir con .exit) |
| Ejecutar un fichero | node fichero.mjs |
| Reejecutar al guardar | node --watch fichero.mjs |
| Proyecto Node | npm init -y + npm pkg set type=module |
| Objeto global universal | globalThis |
| Breakpoint en código | debugger; |
| Modo estricto | 'use strict'; (automático en módulos y clases) |