En la lección anterior apareció varias veces un fantasma: '8' + 4 da '84', 0 se comporta como si fuera falso y null se convierte en 0 al sumar. Todo eso tiene un nombre: coerción de tipos. Es el mecanismo por el que JavaScript convierte automáticamente valores de un tipo a otro, y es —sin exagerar— la fuente de la mayoría de los errores desconcertantes de un principiante. En esta lección lo vas a despejar por completo: cuándo convierte JavaScript por su cuenta, cómo convertir tú de forma explícita, qué valores se consideran verdaderos o falsos, y por qué debes usar siempre ===. Al terminar sabrás tratar con seguridad los datos de un formulario de tarea, que llegan siempre como texto.
Contenido
- Por qué existe la conversión de tipos
- Conversión explícita a número
- Conversión explícita a texto
- Conversión explícita a booleano: truthy y falsy
- Conversión implícita (coerción)
- Operadores de comparación
==frente a===- Comparar cadenas y comparar números
- Comparar objetos: la trampa de la referencia
Object.isy los casos límite- Reglas prácticas de higiene
- Aplicación: validar los datos de un formulario de tarea
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Por qué existe la conversión de tipos
JavaScript se diseñó para ser tolerante. En 1995 se buscaba un lenguaje que no fallara ante datos imperfectos: mejor un resultado raro que una página rota. Por eso, cuando le pides algo que no encaja —sumar un texto con un número, por ejemplo— no protesta: convierte lo que puede y sigue adelante.
Hay dos tipos de conversión:
| Tipo | Quién la hace | Ejemplo |
|---|---|---|
| Explícita | Tú, a propósito | Number('12') → 12 |
| Implícita (coerción) | JavaScript, por su cuenta | '12' * 2 → 24 |
La explícita es tu aliada. La implícita es la que hay que conocer para no ser víctima de ella.
Solo existen tres destinos posibles de conversión: número, texto y booleano. Todo lo demás son variantes de estos tres.
- Conversión explícita a número
2.1 Number()
Convierte el valor completo a número. Si no puede, devuelve NaN.
console.log(Number('12')); // 12
console.log(Number('12.5')); // 12.5
console.log(Number(' 12 ')); // 12 ← ignora espacios alrededor
console.log(Number('')); // 0 ← ¡ojo! la cadena vacía da 0
console.log(Number(' ')); // 0 ← solo espacios, también 0
console.log(Number('12h')); // NaN ← el valor entero debe ser numérico
console.log(Number('alta')); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0 ← ¡ojo!
console.log(Number(undefined)); // NaNDos resultados merecen atención especial porque provocan errores reales:
Number('')es0, noNaN. Si un usuario deja vacío el campo de horas, obtendrás0en lugar de un aviso de error.Number(null)es0peroNumber(undefined)esNaN. Otra incoherencia histórica que hay que conocer.
2.2 parseInt() y parseFloat()
Estas funciones son más permisivas: leen el número desde el principio y se detienen en el primer carácter no válido.
console.log(parseInt('12h')); // 12 ← se queda con lo que entiende
console.log(parseInt('12.9')); // 12 ← trunca los decimales
console.log(parseFloat('12.9h')); // 12.9 ← conserva decimales
console.log(parseInt('h12')); // NaN ← no empieza por número
console.log(parseInt('')); // NaN ← aquí sí da NaN, no 0Usa siempre parseInt con la base 10 como segundo argumento. Es un hábito heredado de una época en la que un texto que empezaba por 0 se interpretaba en octal:
Comparativa:
| Valor | Number() |
parseInt() |
parseFloat() |
|---|---|---|---|
'12' |
12 |
12 |
12 |
'12.9' |
12.9 |
12 |
12.9 |
'12h' |
NaN |
12 |
12 |
'12 horas' |
NaN |
12 |
12 |
'' |
0 |
NaN |
NaN |
' ' |
0 |
NaN |
NaN |
'alta' |
NaN |
NaN |
NaN |
true |
1 |
NaN |
NaN |
null |
0 |
NaN |
NaN |
Cuál usar: Number() cuando exijas que el valor entero sea un número (lo habitual al validar datos). parseInt/parseFloat cuando quieras extraer un número de un texto que lleva unidades ('12px', '8 horas').
2.3 El truco del + unario
Poner un + delante de un valor lo convierte a número, exactamente igual que Number():
const horasTexto = '12';
console.log(+horasTexto); // 12
console.log(typeof +horasTexto); // 'number'Es breve y muy usado, pero Number() se lee mejor y no se confunde con una suma. Reconócelo cuando lo veas; escribe Number().
2.4 Validar un número de verdad
Combinando lo anterior, así se comprueba correctamente que un texto contiene un número usable:
const entrada = '12.5';
const horas = Number(entrada);
const esNumeroValido = !Number.isNaN(horas) && entrada.trim() !== '';
console.log(esNumeroValido); // trueSe necesitan las dos comprobaciones: Number.isNaN descarta los textos no numéricos, y el trim() !== '' descarta la cadena vacía, que Number() convertiría en 0 sin protestar.
- Conversión explícita a texto
3.1 String()
Convierte cualquier valor a texto. Funciona con todo, incluidos null y undefined.
console.log(String(12)); // '12'
console.log(String(12.5)); // '12.5'
console.log(String(true)); // 'true'
console.log(String(null)); // 'null'
console.log(String(undefined)); // 'undefined'
console.log(String(NaN)); // 'NaN'
console.log(String([1, 2, 3])); // '1,2,3'
console.log(String({ a: 1 })); // '[object Object]'Esa última línea es un clásico: si alguna vez ves [object Object] en pantalla, has convertido un objeto a texto sin querer.
3.2 .toString()
Es un método del propio valor. Hace lo mismo que String(), con una diferencia crítica:
console.log((12).toString()); // '12'
console.log(true.toString()); // 'true'
// console.log(null.toString()); // TypeError
// console.log(undefined.toString()); // TypeErrorString() es más seguro porque nunca lanza un error. .toString() falla ante null y undefined, que son precisamente los casos en los que más falta te hace no fallar.
.toString() sí tiene una habilidad exclusiva: convertir a otra base numérica.
console.log((255).toString(2)); // '11111111' (binario)
console.log((255).toString(16)); // 'ff' (hexadecimal)3.3 Template literals
La forma más natural de convertir a texto en el día a día:
Todo lo que metas en ${} se convierte a texto automáticamente.
| Método | Seguro con null/undefined |
Legibilidad | Uso recomendado |
|---|---|---|---|
String(valor) |
Sí | Alta | Conversión explícita general |
valor.toString() |
No | Alta | Cambio de base numérica |
`${valor}` |
Sí | Muy alta | Componer mensajes |
valor + '' |
Sí | Baja | Evitar |
- Conversión explícita a booleano: truthy y falsy
Cuando JavaScript necesita un booleano (en un if, en un &&, en un !), convierte lo que le des. Los valores que se convierten en false se llaman falsy; el resto, truthy.
4.1 La lista completa de valores falsy
Solo hay ocho valores falsy en JavaScript. Merece la pena memorizarlos, porque todo lo demás es truthy:
| Valor falsy | Comentario |
|---|---|
false |
El booleano falso |
0 |
El cero |
-0 |
El cero negativo |
0n |
El cero de tipo bigint |
'' |
La cadena vacía (también "" y ``) |
null |
|
undefined |
|
NaN |
console.log(Boolean(false)); // false
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false4.2 Los truthy que más sorprenden
Como todo lo que no está en la lista es truthy, algunos casos chocan:
console.log(Boolean('0')); // true ← ¡el TEXTO '0' es truthy!
console.log(Boolean('false')); // true ← el TEXTO 'false' también
console.log(Boolean(' ')); // true ← un espacio no es cadena vacía
console.log(Boolean([])); // true ← ¡un array vacío es truthy!
console.log(Boolean({})); // true ← un objeto vacío también
console.log(Boolean(-1)); // true ← cualquier número que no sea 0Los dos que más problemas causan en la práctica:
'0'es truthy. Si un formulario devuelve'0'horas,if (horas)se cumplirá.[]es truthy. Para saber si una lista de etiquetas está vacía hay que miraretiquetas.length === 0, noif (!etiquetas).
const etiquetas = [];
if (etiquetas) {
console.log('Esto se ejecuta SIEMPRE, aunque la lista esté vacía');
}
if (etiquetas.length === 0) {
console.log('Así sí se detecta una lista vacía'); // ← correcto
}
- Conversión implícita (coerción)
Ahora que sabes convertir tú, veamos cuándo lo hace JavaScript por su cuenta.
5.1 Coerción a texto: el +
Si alguno de los operandos de + es un string, el otro se convierte a string.
console.log('Horas: ' + 12); // 'Horas: 12'
console.log(12 + ''); // '12'
console.log('12' + true); // '12true'
console.log('12' + null); // '12null'
console.log('12' + undefined); // '12undefined'
console.log('12' + [1, 2]); // '121,2'5.2 Coerción a número: los demás operadores aritméticos
-, *, /, % y ** siempre convierten a número:
console.log('12' - 4); // 8
console.log('12' * '2'); // 24
console.log(true + 1); // 2 ← true se convierte en 1
console.log(false + 1); // 1 ← false se convierte en 0
console.log(null + 5); // 5 ← null se convierte en 0
console.log(undefined + 5); // NaN ← undefined se convierte en NaN
console.log([] + 1); // '1' ← el array vacío se convierte a ''
console.log([5] * 2); // 10 ← [5] se convierte a '5' y luego a 5Las cuatro últimas líneas son el tipo de rareza que hace famoso a JavaScript. No las memorices: memoriza la conclusión, que es no mezclar tipos.
5.3 El caso que rompe cálculos reales
Este es el error práctico que te vas a encontrar de verdad:
// Datos que llegan de un formulario: SIEMPRE son texto
const horasTarea1 = '12';
const horasTarea2 = '8';
console.log(horasTarea1 + horasTarea2); // '128' ← ¡mal!
// Convirtiendo antes de operar
console.log(Number(horasTarea1) + Number(horasTarea2)); // 20 ← correctoY el que ocurre cuando solo uno de los valores es texto:
const horasIvan = 12; // número
const horasLucia = '8'; // texto (viene de un input)
console.log(horasIvan + horasLucia); // '128' ← concatena
console.log(horasIvan - horasLucia); // 4 ← resta bien
console.log(horasIvan * horasLucia); // 96 ← multiplica bienQue unos operadores funcionen y otros no es lo que hace tan difícil de localizar este fallo: el programa parece funcionar hasta que llega a una suma.
- Operadores de comparación
Los operadores relacionales devuelven siempre un booleano:
| Operador | Nombre | Ejemplo | Resultado |
|---|---|---|---|
> |
Mayor que | 12 > 8 |
true |
< |
Menor que | 12 < 8 |
false |
>= |
Mayor o igual | 12 >= 12 |
true |
<= |
Menor o igual | 8 <= 12 |
true |
== |
Igualdad laxa | '12' == 12 |
true |
=== |
Igualdad estricta | '12' === 12 |
false |
!= |
Desigualdad laxa | '12' != 12 |
false |
!== |
Desigualdad estricta | '12' !== 12 |
true |
const horasEstimadas = 12;
const MAX_HORAS_DIA = 8;
console.log(horasEstimadas > MAX_HORAS_DIA); // true
console.log(horasEstimadas <= MAX_HORAS_DIA); // false
== frente a ===
== frente a ===Aquí está el corazón de la lección.
===(igualdad estricta) compara valor y tipo. Si los tipos difieren, devuelvefalsesin más.==(igualdad laxa) convierte los valores a un tipo común antes de comparar.
console.log('12' === 12); // false ← tipos distintos
console.log('12' == 12); // true ← convierte '12' a 12 y compara7.1 Los casos clásicos de ==
| Comparación | == |
=== |
Por qué |
|---|---|---|---|
'5' == 5 |
true |
false |
El texto se convierte a número |
'' == 0 |
true |
false |
La cadena vacía se convierte a 0 |
'0' == 0 |
true |
false |
'0' se convierte a 0 |
'' == '0' |
false |
false |
Ambos son texto: se comparan tal cual |
false == 0 |
true |
false |
false se convierte a 0 |
false == '' |
true |
false |
Ambos se convierten a 0 |
null == undefined |
true |
false |
Regla especial del lenguaje |
null == 0 |
false |
false |
null solo es laxamente igual a undefined |
NaN == NaN |
false |
false |
NaN nunca es igual a nada, ni a sí mismo |
[] == false |
true |
false |
[] → '' → 0, y false → 0 |
[] == '' |
true |
false |
El array vacío se convierte a cadena vacía |
Fíjate en la incoherencia demoledora: '' == 0 es true y '0' == 0 es true, pero '' == '0' es false. Es decir, == no es transitivo. Dos valores pueden ser "iguales" a un tercero y no serlo entre sí. Esto por sí solo debería bastar para desterrar == de tu código.
7.2 La única excepción tolerada
Hay un uso de == que muchos equipos aceptan: comprobar de una vez si un valor es null o undefined.
const revisor = null;
// Con == cubre los dos casos de una sola vez
if (revisor == null) {
console.log('Sin revisor asignado');
}
// Equivalente estricto, más explícito
if (revisor === null || revisor === undefined) {
console.log('Sin revisor asignado');
}Aun así, hoy existe una alternativa más limpia con ??, que ya conoces:
7.3 El caso de NaN
NaN es el único valor de JavaScript que no es igual a sí mismo, ni con == ni con ===:
Por eso existe Number.isNaN():
Cuidado con la función global antigua isNaN(), que convierte antes de comprobar y da falsos positivos:
console.log(isNaN('alta')); // true ← convierte 'alta' a NaN primero
console.log(Number.isNaN('alta')); // false ← 'alta' es un string, no NaNUsa siempre Number.isNaN().
- Comparar cadenas y comparar números
Los operadores < y > se comportan de forma distinta según los tipos.
Si ambos son texto, se comparan carácter a carácter según su código Unicode (aproximadamente, orden alfabético):
console.log('alta' < 'baja'); // true ← 'a' va antes que 'b'
console.log('Iván' < 'iván'); // true ← las mayúsculas van antes
console.log('10' < '9'); // true ← ¡comparación de TEXTO! '1' < '9'Esa última línea es una trampa clásica: como texto, '10' es menor que '9' porque se compara el primer carácter.
Si alguno es número, ambos se convierten a número:
Para ordenar textos con criterio de idioma (acentos, eñes) existe localeCompare:
8.1 Por qué las fechas ISO son tan cómodas
Aquí se ve por qué en Nómada Tareas guardamos las fechas como texto 'yyyy-mm-dd':
const fecha1 = '2026-09-30';
const fecha2 = '2026-11-05';
console.log(fecha1 < fecha2); // true — orden cronológico correctoEl formato ISO tiene la propiedad de que su orden alfabético coincide con su orden cronológico, porque los componentes van de mayor a menor magnitud y con ceros a la izquierda. Con '30/09/2026' esto no funcionaría en absoluto.
- Comparar objetos: la trampa de la referencia
Recuerda de la lección de tipos: los objetos y arrays se manejan por referencia. Al compararlos, JavaScript no mira el contenido: mira si son el mismo objeto en memoria.
const etiquetas1 = ['diseño', 'espacio'];
const etiquetas2 = ['diseño', 'espacio'];
console.log(etiquetas1 === etiquetas2); // false ← contenido igual, objetos distintos
console.log(etiquetas1 == etiquetas2); // false ← == tampoco ayuda
const etiquetas3 = etiquetas1;
console.log(etiquetas1 === etiquetas3); // true ← es el mismo objetoLo mismo con objetos:
const tareaA = { id: 1, titulo: 'Revisar facturas' };
const tareaB = { id: 1, titulo: 'Revisar facturas' };
console.log(tareaA === tareaB); // false
console.log(tareaA.id === tareaB.id); // true ← comparando primitivos, síflowchart TD
A["etiquetas1"] --> M1["Memoria: ['diseño','espacio']"]
B["etiquetas2"] --> M2["Memoria: ['diseño','espacio']"]
C["etiquetas3"] --> M1
M1 -.->|"=== M2"| R["false: son<br/>zonas distintas"]
Regla práctica: para comparar dos tareas, compara sus campos (normalmente el id), nunca los objetos completos con ===. Las técnicas para comparar contenidos se ven en JSON y Copias de Objetos.
Object.is y los casos límite
Object.is y los casos límiteObject.is() (ES2015) se comporta como === salvo en dos casos donde === tiene un comportamiento discutible:
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true ← más razonable
console.log(0 === -0); // true
console.log(Object.is(0, -0)); // false ← distingue el cero negativo| Comparación | == |
=== |
Object.is |
|---|---|---|---|
'12' y 12 |
true |
false |
false |
null y undefined |
true |
false |
false |
NaN y NaN |
false |
false |
true |
0 y -0 |
true |
true |
false |
'alta' y 'alta' |
true |
true |
true |
En el día a día usarás ===. Object.is es útil cuando te importe distinguir NaN o el cero negativo, situaciones poco frecuentes pero reales en cálculos numéricos.
- Reglas prácticas de higiene
Cinco reglas que te ahorrarán la mayor parte de los problemas de esta lección:
- Usa siempre
===y!==. Sin excepciones mientras aprendes. Las herramientas de calidad de código que verás en el Módulo 8 te avisarán si se te escapa un==. - Convierte explícitamente antes de operar. Si un dato puede ser texto, aplícale
Number()antes de sumarlo. No confíes en la coerción. - No mezcles tipos en una misma variable. Si
horases un número, que sea siempre un número. - Comprueba la ausencia de valor explícitamente.
if (valor === null)ovalor ?? defecto, en lugar de confiar en truthy/falsy. - Ojo con
0,''y[]. Los dos primeros son falsy aunque sean datos válidos; el tercero es truthy aunque esté vacío.
flowchart TD
A["Recibes un dato"] --> B{"¿De dónde<br/>viene?"}
B -->|"Formulario, URL,<br/>almacenamiento"| C["Es TEXTO,<br/>siempre"]
B -->|"Tu propio código"| D["Ya tiene el<br/>tipo correcto"]
C --> E["Convierte con<br/>Number() o String()"]
E --> F["Valida con<br/>Number.isNaN() y trim()"]
F --> G["Compara con ==="]
D --> G
- Aplicación: validar los datos de un formulario de tarea
Marta rellena un formulario para dar de alta una tarea en Nómada Tareas. Los campos de un formulario web devuelven siempre texto, incluso los numéricos y los de fecha. Vamos a comprobar los datos antes de usarlos.
'use strict';
// --- Datos tal y como llegan de un formulario: TODO son strings ----
const idTexto = '5';
const tituloTexto = ' Preparar el taller de serigrafía ';
const responsableTexto = ''; // no se ha rellenado
const prioridadTexto = 'media';
const horasTexto = '6';
const fechaLimiteTexto = '2026-10-15';
const etiquetasTexto = 'taller, formación';
// --- Conversión explícita -----------------------------------------
const id = Number(idTexto);
const titulo = tituloTexto.trim(); // quita los espacios sobrantes
const horasEstimadas = Number(horasTexto);
// --- Validaciones --------------------------------------------------
// 1. El id debe ser un número válido y positivo
const idEsValido = !Number.isNaN(id) && id > 0;
// 2. El título no puede estar vacío una vez recortado
const tituloEsValido = titulo !== '';
// 3. Las horas: número válido, mayor que 0. Cuidado: Number('') es 0
const horasSonValidas =
horasTexto.trim() !== '' && !Number.isNaN(horasEstimadas) && horasEstimadas > 0;
// 4. La prioridad debe ser uno de los tres valores permitidos
const prioridadEsValida =
prioridadTexto === 'alta' ||
prioridadTexto === 'media' ||
prioridadTexto === 'baja';
// 5. La fecha ISO tiene siempre 10 caracteres y no puede ser pasada
const HOY = '2026-08-18';
const fechaEsValida =
fechaLimiteTexto.length === 10 && fechaLimiteTexto >= HOY;
// 6. El responsable puede faltar: usamos null a propósito
const responsable = responsableTexto.trim() === '' ? null : responsableTexto.trim();
// 7. Las etiquetas: si el texto está vacío, lista vacía
// split(', ') parte el texto por el separador y devuelve un array
const etiquetas =
etiquetasTexto.trim() === '' ? [] : etiquetasTexto.split(', ');
// --- Resultado global ----------------------------------------------
const formularioEsValido =
idEsValido && tituloEsValido && horasSonValidas &&
prioridadEsValida && fechaEsValida;
// --- Salida --------------------------------------------------------
console.log('=== Validación de la tarea ===');
console.log(`id (${typeof id}): ${id} → ${idEsValido ? 'OK' : 'ERROR'}`);
console.log(`título: "${titulo}" → ${tituloEsValido ? 'OK' : 'ERROR'}`);
console.log(`horas (${typeof horasEstimadas}): ${horasEstimadas} → ${horasSonValidas ? 'OK' : 'ERROR'}`);
console.log(`prioridad: ${prioridadTexto} → ${prioridadEsValida ? 'OK' : 'ERROR'}`);
console.log(`fecha límite: ${fechaLimiteTexto} → ${fechaEsValida ? 'OK' : 'ERROR'}`);
console.log(`responsable: ${responsable ?? 'Sin asignar'}`);
console.log(`etiquetas (${etiquetas.length}): ${etiquetas.join(' · ')}`);
console.log(`\nFormulario válido: ${formularioEsValido ? 'SÍ' : 'NO'}`);Salida:
=== Validación de la tarea === id (number): 5 → OK título: "Preparar el taller de serigrafía" → OK horas (number): 6 → OK prioridad: media → OK fecha límite: 2026-10-15 → OK responsable: Sin asignar etiquetas (2): taller · formación Formulario válido: SÍ
Decisiones importantes de este código:
- Todo se convierte explícitamente.
Number(idTexto)yNumber(horasTexto)en lugar de confiar en que el+se porte bien. .trim()antes de validar textos. Un título de solo espacios pasaría una comprobación ingenua.- La doble comprobación de horas.
horasTexto.trim() !== ''es imprescindible porqueNumber('')devuelve0, noNaN. Sin ella, un campo vacío pasaría como "0 horas". ===en todas las comparaciones. La prioridad se compara con los tres valores exactos.- La fecha se compara como texto aprovechando el formato ISO.
'2026-10-15' >= '2026-08-18'estrue. - El responsable ausente es
null, no''. Estamos afirmando "no hay responsable", no guardando un texto vacío. - Las etiquetas ausentes son
[], nonull. Una lista vacía sigue siendo una lista, y así todo el código posterior puede tratarla igual.
La validación desde el punto de vista de la interfaz —leer el formulario real, mostrar mensajes de error junto a cada campo, impedir el envío— es materia de Manejo y Validación de Formularios. Aquí nos hemos centrado en la lógica de conversión y comparación, que es la parte que de verdad decide si un dato es correcto.
Errores Comunes y Consejos
Errores comunes
- Usar
==por costumbre. Genera errores que aparecen meses después con datos concretos. Usa===. - Olvidar que
Number('')es0. Un campo vacío pasa como cero horas y nadie se entera. - Confiar en
if (valor)para números. Sivalores0, la condición no se cumple aunque el dato sea legítimo. - Comprobar si un array está vacío con
if (!lista). Un array vacío es truthy. Usalista.length === 0. - Comparar
NaNcon===. Nunca funciona. UsaNumber.isNaN(). - Usar la función global
isNaN(). Convierte antes de comprobar y da falsos positivos. UsaNumber.isNaN(). - Comparar objetos o arrays con
===esperando comparar el contenido. Compara referencias. Compara sus campos. - Llamar a
.toString()sobre algo que puede sernull.TypeErrorgarantizado. UsaString(). - Comparar números guardados como texto con
<o>.'10' < '9'estrue. Convierte antes. - Sumar directamente valores de un formulario.
'12' + '8'es'128'.
Consejos
- Convierte en la frontera. En cuanto un dato entra en tu programa (formulario, URL, almacenamiento), conviértelo al tipo correcto. A partir de ahí, todo el código puede confiar en él.
- Memoriza los ocho valores falsy. Es la tabla que más rentabilidad te va a dar de todo el módulo.
- Cuando algo se comporte de forma extraña, imprime
typeof.console.log(typeof x, x)resuelve la mitad de los misterios en dos segundos. - Da nombre a las validaciones:
const horasSonValidas = .... Unifcon cinco condiciones sin nombre es ilegible. - Usa fechas ISO
'yyyy-mm-dd'y podrás compararlas y ordenarlas como texto sin ninguna librería. Number()para validar,parseInt/parseFloatpara extraer.
Ejercicios
Ejercicio 1: Predice las conversiones
Escribe el resultado de cada línea:
console.log(Number(' 25 ')); // A
console.log(Number('')); // B
console.log(Number('25 horas')); // C
console.log(parseInt('25 horas')); // D
console.log(parseFloat('7.5h')); // E
console.log(Number(null)); // F
console.log(Number(undefined)); // G
console.log(String(null)); // H
console.log(Boolean('0')); // I
console.log(Boolean([])); // J
console.log(Boolean('')); // K
console.log(Boolean(-1)); // LEjercicio 2: == frente a ===
Rellena la tabla indicando el resultado de cada comparación con los dos operadores, y explica los tres casos que te parezcan más sorprendentes:
| Comparación | == |
=== |
|---|---|---|
'6' ? 6 |
||
'' ? 0 |
||
'' ? '0' |
||
null ? undefined |
||
null ? 0 |
||
false ? 0 |
||
NaN ? NaN |
||
'alta' ? 'alta' |
Ejercicio 3: Validador de horas de una tarea
Escribe un script que valide el campo "horas estimadas" de un formulario de Nómada Tareas. Debe comprobar, para cada valor de entrada, que:
- No está vacío ni contiene solo espacios.
- Es un número válido.
- Es mayor que
0. - No supera las
40horas (una semana completa).
Para cada entrada, imprime el valor original, el valor convertido y el resultado (OK o el motivo del error).
Prueba con estas entradas: '8', '0', '', ' ', 'ocho', '7.5', '45', '8 horas'.
Soluciones
Ejercicio 1
| Línea | Resultado | Explicación |
|---|---|---|
| A | 25 |
Number() ignora los espacios de alrededor |
| B | 0 |
La cadena vacía se convierte a 0, no a NaN |
| C | NaN |
Number() exige que todo el texto sea numérico |
| D | 25 |
parseInt lee desde el principio y se detiene en el espacio |
| E | 7.5 |
parseFloat conserva decimales y se detiene en la h |
| F | 0 |
null se convierte numéricamente a 0 |
| G | NaN |
undefined no tiene equivalente numérico |
| H | 'null' |
String() funciona con null (a diferencia de .toString()) |
| I | true |
El texto '0' no es la cadena vacía, así que es truthy |
| J | true |
Un array vacío es un objeto, y todos los objetos son truthy |
| K | false |
La cadena vacía está en la lista de falsy |
| L | true |
Solo el 0 es falsy; cualquier otro número es truthy |
Ejercicio 2
| Comparación | == |
=== |
|---|---|---|
'6' y 6 |
true |
false |
'' y 0 |
true |
false |
'' y '0' |
false |
false |
null y undefined |
true |
false |
null y 0 |
false |
false |
false y 0 |
true |
false |
NaN y NaN |
false |
false |
'alta' y 'alta' |
true |
true |
Los tres casos más sorprendentes:
'' == 0estruepero'' == '0'esfalse. Cuando los dos operandos son texto,==no convierte nada y los compara tal cual. Esto demuestra que==no es transitivo:''es "igual" a0y'0'es "igual" a0, pero''y'0'no son iguales entre sí.null == undefinedestrueperonull == 0esfalse. No hay lógica de conversión detrás: es una regla especial escrita explícitamente en la especificación.nullsolo es laxamente igual aundefinedy a sí mismo.NaN == NaNesfalse. El único valor del lenguaje que no es igual a sí mismo, siguiendo el estándar IEEE 754 de coma flotante. Por eso existeNumber.isNaN().
Ejercicio 3
'use strict';
// --- Constantes de negocio -----------------------------------------
const MIN_HORAS = 0;
const MAX_HORAS = 40;
// --- Entradas a probar ---------------------------------------------
const entrada = '8'; // cámbiala para probar las demás
// --- Validación paso a paso ----------------------------------------
const recortada = entrada.trim();
const horas = Number(recortada);
// Ternario encadenado: el orden de las comprobaciones es deliberado
const resultado =
recortada === '' ? 'ERROR: el campo está vacío' :
Number.isNaN(horas) ? 'ERROR: no es un número válido' :
horas <= MIN_HORAS ? 'ERROR: debe ser mayor que 0' :
horas > MAX_HORAS ? `ERROR: no puede superar ${MAX_HORAS} horas` :
'OK';
console.log(`"${entrada}" → ${horas} (${typeof horas}) → ${resultado}`);Resultados esperados para todas las entradas:
| Entrada | trim() |
Number() |
Resultado |
|---|---|---|---|
'8' |
'8' |
8 |
OK |
'0' |
'0' |
0 |
ERROR: debe ser mayor que 0 |
'' |
'' |
0 |
ERROR: el campo está vacío |
' ' |
'' |
0 |
ERROR: el campo está vacío |
'ocho' |
'ocho' |
NaN |
ERROR: no es un número válido |
'7.5' |
'7.5' |
7.5 |
OK |
'45' |
'45' |
45 |
ERROR: no puede superar 40 horas |
'8 horas' |
'8 horas' |
NaN |
ERROR: no es un número válido |
Tres observaciones clave:
- El orden de las comprobaciones importa. La de cadena vacía va primero, porque
Number('')da0y esa entrada acabaría dando el mensaje "debe ser mayor que 0", que es confuso y no describe el problema real. ' 'y''producen el mismo error gracias al.trim()previo.'8 horas'se rechaza porque hemos usadoNumber(). Si hubiéramos usadoparseInt, habría pasado como8en silencio. En una validación de entrada eso sería un error:Number()es la elección correcta para validar.
Conclusión
Has despejado el terreno donde más se tropieza en JavaScript. Sabes convertir explícitamente con Number(), parseInt(), parseFloat(), String(), .toString() y Boolean(), y conoces las trampas de cada uno (Number('') es 0, .toString() falla con null). Dominas la conversión implícita: el + concatena si hay un string, los demás operadores aritméticos convierten a número. Te sabes la lista completa de los ocho valores falsy y recuerdas que '0' y [] son truthy. Distingues == de === y has visto por qué la igualdad laxa ni siquiera es transitiva. Sabes que las cadenas se comparan alfabéticamente —y por qué eso hace tan cómodas las fechas ISO—, que los objetos se comparan por referencia, y que existe Object.is para los casos límite de NaN y -0.
Y lo más práctico: has escrito un validador completo para los datos de un formulario de tarea de Nómada Tareas, esos que llegan siempre como texto.
Con esto cierras la caja de herramientas básica: entorno, sintaxis, variables, tipos, operadores y comparaciones. Ya tienes todo lo necesario para entender el proyecto en su conjunto. En la última lección del módulo, El Proyecto del Curso: Nómada Tareas, conocerás a fondo Taller Nómada y su problema, el modelo de datos canónico de una tarea con todos sus campos y valores permitidos, y el mapa completo de qué construirás en cada módulo del curso.
Curso de JavaScript: De Principiante a Avanzado
Módulo 1: Introducción a JavaScript
- ¿Qué es JavaScript?
- Configuración de tu Entorno de Desarrollo
- Tu Primer Programa en JavaScript
- Sintaxis y Conceptos Básicos de JavaScript
- Variables y Tipos de Datos
- Operadores Básicos
- Conversión de Tipos y Comparaciones
- El Proyecto del Curso: Nómada Tareas
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for, while, do-while
- Sentencias Switch
- Control del Flujo: break, continue y Bucles Anidados
- Manejo de Errores con try-catch
Módulo 3: Funciones
- Definición y Llamada de Funciones
- Expresiones de Función y Funciones Flecha
- Parámetros y Valores de Retorno
- Ámbito y Closures
- Hoisting y el Contexto de Ejecución
- Funciones de Orden Superior
- Recursividad
Módulo 4: Objetos y Arrays
- Introducción a los Objetos
- Métodos de Objeto y la Palabra Clave
this - Arrays: Conceptos Básicos y Métodos
- Iteración sobre Arrays
- Buscar, Ordenar y Agregar Datos: find, sort y reduce
- Desestructuración de Arrays
- Desestructuración de Objetos, Spread y Rest
- JSON y Copias de Objetos
Módulo 5: Objetos y Funciones Avanzadas
- Prototipos y Herencia
- Clases y Programación Orientada a Objetos
- Encapsulación: Getters, Setters y Campos Privados
- Módulos e Importación/Exportación
- JavaScript Asíncrono: Callbacks
- Promesas y Async/Await
- El Bucle de Eventos y la Cola de Microtareas
- Iteradores y Generadores
Módulo 6: El Modelo de Objetos del Documento (DOM)
- Introducción al DOM
- Selección y Manipulación de Elementos del DOM
- Manejo de Eventos
- Propagación, Delegación y Eventos Personalizados
- Creación y Eliminación de Elementos del DOM
- Renderizado de Listas y Plantillas HTML
- Manejo y Validación de Formularios
Módulo 7: APIs del Navegador y Temas Avanzados
- Almacenamiento Local y de Sesión
- Fetch API y AJAX
- Peticiones Robustas: Errores, Timeouts y AbortController
- WebSockets
- Service Workers y Aplicaciones Web Progresivas (PWAs)
- APIs del Navegador Esenciales
- Introducción a WebAssembly
Módulo 8: Pruebas y Depuración
- Depuración de JavaScript
- Calidad de Código: ESLint, Prettier y Convenciones
- Pruebas Unitarias con Jest
- Dobles de Prueba: Mocks, Stubs y Spies
- Pruebas de Integración
- Pruebas de Extremo a Extremo con Cypress
Módulo 9: Rendimiento y Optimización
- Medir Antes de Optimizar: DevTools y Web Vitals
- Optimización del Rendimiento de JavaScript
- Gestión de Memoria
- Manipulación Eficiente del DOM
- Carga Perezosa y División de Código
Módulo 10: Frameworks y Librerías de JavaScript
- Por Qué Existen los Frameworks
- Introducción a React
- Gestión de Estado con Redux
- Conceptos Básicos de Vue.js
- Conceptos Básicos de Angular
- Elegir el Framework Adecuado
