A la lliçó anterior va aparèixer diverses vegades un fantasma: '8' + 4 dona '84', 0 es comporta com si fos fals i null es converteix en 0 en sumar. Tot això té un nom: coerció de tipus. És el mecanisme pel qual JavaScript converteix automàticament valors d'un tipus a un altre, i és —sense exagerar— la font de la majoria dels errors desconcertants d'un principiant. En aquesta lliçó el desbrossaràs completament: quan converteix JavaScript pel seu compte, com convertir tu de manera explícita, quins valors es consideren certs o falsos, i per què has de fer servir sempre ===. En acabar sabràs tractar amb seguretat les dades d'un formulari de tasca, que arriben sempre com a text.

Contingut

  1. Per què existeix la conversió de tipus
  2. Conversió explícita a nombre
  3. Conversió explícita a text
  4. Conversió explícita a booleà: truthy i falsy
  5. Conversió implícita (coerció)
  6. Operadors de comparació
  7. == enfront de ===
  8. Comparar cadenes i comparar nombres
  9. Comparar objectes: el parany de la referència
  10. Object.is i els casos límit
  11. Regles pràctiques d'higiene
  12. Aplicació: validar les dades d'un formulari de tasca
  13. Errors Habituals i Consells
  14. Exercicis
  15. Conclusió

  1. Per què existeix la conversió de tipus

JavaScript es va dissenyar per ser tolerant. El 1995 es buscava un llenguatge que no fallés davant de dades imperfectes: millor un resultat estrany que una pàgina trencada. Per això, quan li demanes una cosa que no encaixa —sumar un text amb un nombre, per exemple— no protesta: converteix el que pot i tira endavant.

Hi ha dos tipus de conversió:

Tipus Qui la fa Exemple
Explícita Tu, a propòsit Number('12')12
Implícita (coerció) JavaScript, pel seu compte '12' * 224

L'explícita és la teva aliada. La implícita és la que cal conèixer per no ser-ne víctima.

Només existeixen tres destinacions possibles de conversió: nombre, text i booleà. Tota la resta són variants d'aquestes tres.

  1. Conversió explícita a nombre

2.1 Number()

Converteix el valor sencer a nombre. Si no pot, retorna NaN.

console.log(Number('12'));      // 12
console.log(Number('12.5'));    // 12.5
console.log(Number('  12  '));  // 12  ← ignora els espais del voltant
console.log(Number(''));        // 0   ← compte! la cadena buida dona 0
console.log(Number('   '));     // 0   ← només espais, també 0
console.log(Number('12h'));     // NaN ← el valor sencer ha de ser numèric
console.log(Number('alta'));    // NaN
console.log(Number(true));      // 1
console.log(Number(false));     // 0
console.log(Number(null));      // 0   ← compte!
console.log(Number(undefined)); // NaN

Dos resultats mereixen atenció especial perquè provoquen errors reals:

  • Number('') és 0, no NaN. Si un usuari deixa buit el camp d'hores, obtindràs 0 en lloc d'un avís d'error.
  • Number(null) és 0 però Number(undefined) és NaN. Una altra incoherència històrica que cal conèixer.

2.2 parseInt() i parseFloat()

Aquestes funcions són més permissives: llegeixen el nombre des del principi i s'aturen al primer caràcter no vàlid.

console.log(parseInt('12h'));      // 12   ← es queda amb el que entén
console.log(parseInt('12.9'));     // 12   ← trunca els decimals
console.log(parseFloat('12.9h'));  // 12.9 ← conserva decimals
console.log(parseInt('h12'));      // NaN  ← no comença per nombre
console.log(parseInt(''));         // NaN  ← aquí sí que dona NaN, no 0

Fes servir sempre parseInt amb la base 10 com a segon argument. És un hàbit heretat d'una època en què un text que començava per 0 s'interpretava en octal:

console.log(parseInt('12', 10)); // 12 — sense ambigüitat

Comparativa:

Valor Number() parseInt() parseFloat()
'12' 12 12 12
'12.9' 12.9 12 12.9
'12h' NaN 12 12
'12 hores' NaN 12 12
'' 0 NaN NaN
' ' 0 NaN NaN
'alta' NaN NaN NaN
true 1 NaN NaN
null 0 NaN NaN

Quina fer servir: Number() quan exigeixis que el valor sencer sigui un nombre (el més habitual en validar dades). parseInt/parseFloat quan vulguis extreure un nombre d'un text que porta unitats ('12px', '8 hores').

2.3 El truc del + unari

Posar un + davant d'un valor el converteix a nombre, exactament igual que Number():

const horesText = '12';
console.log(+horesText);        // 12
console.log(typeof +horesText); // 'number'

És breu i molt utilitzat, però Number() es llegeix millor i no es confon amb una suma. Reconeix-lo quan el vegis; escriu Number().

2.4 Validar un nombre de debò

Combinant tot l'anterior, així es comprova correctament que un text conté un nombre utilitzable:

const entrada = '12.5';
const hores = Number(entrada);

const esNombreValid = !Number.isNaN(hores) && entrada.trim() !== '';
console.log(esNombreValid); // true

Calen les dues comprovacions: Number.isNaN descarta els textos no numèrics, i el trim() !== '' descarta la cadena buida, que Number() convertiria en 0 sense protestar.

  1. Conversió explícita a text

3.1 String()

Converteix qualsevol valor a text. Funciona amb tot, inclosos null i 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]'

Aquesta última línia és un clàssic: si algun cop veus [object Object] a la pantalla, has convertit un objecte a text sense voler.

3.2 .toString()

És un mètode del valor mateix. Fa el mateix que String(), amb una diferència crítica:

console.log((12).toString());     // '12'
console.log(true.toString());     // 'true'

// console.log(null.toString());      // TypeError
// console.log(undefined.toString()); // TypeError

String() és més segur perquè no llança mai cap error. .toString() falla davant de null i undefined, que són precisament els casos en què més falta et fa no fallar.

.toString() sí que té una habilitat exclusiva: convertir a una altra base numèrica.

console.log((255).toString(2));  // '11111111' (binari)
console.log((255).toString(16)); // 'ff' (hexadecimal)

3.3 Template literals

La manera més natural de convertir a text en el dia a dia:

const hores = 12;
const missatge = `${hores}`;
console.log(typeof missatge); // 'string'

Tot el que fiquis a ${} es converteix a text automàticament.

Mètode Segur amb null/undefined Llegibilitat Ús recomanat
String(valor) Alta Conversió explícita general
valor.toString() No Alta Canvi de base numèrica
`${valor}` Molt alta Compondre missatges
valor + '' Baixa Evitar

  1. Conversió explícita a booleà: truthy i falsy

Quan JavaScript necessita un booleà (en un if, en un &&, en un !), converteix el que li donis. Els valors que es converteixen en false s'anomenen falsy; la resta, truthy.

4.1 La llista completa de valors falsy

Només hi ha vuit valors falsy en JavaScript. Val la pena memoritzar-los, perquè tota la resta és truthy:

Valor falsy Comentari
false El booleà fals
0 El zero
-0 El zero negatiu
0n El zero de tipus bigint
'' La cadena buida (també "" i ``)
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));       // false

4.2 Els truthy que més sorprenen

Com que tot el que no és a la llista és truthy, alguns casos xoquen:

console.log(Boolean('0'));       // true  ← el TEXT '0' és truthy!
console.log(Boolean('false'));   // true  ← el TEXT 'false' també
console.log(Boolean(' '));       // true  ← un espai no és cadena buida
console.log(Boolean([]));        // true  ← un array buit és truthy!
console.log(Boolean({}));        // true  ← un objecte buit també
console.log(Boolean(-1));        // true  ← qualsevol nombre que no sigui 0

Els dos que més problemes causen a la pràctica:

  • '0' és truthy. Si un formulari retorna '0' hores, if (hores) es complirà.
  • [] és truthy. Per saber si una llista d'etiquetes és buida cal mirar etiquetes.length === 0, no if (!etiquetes).
const etiquetes = [];

if (etiquetes) {
  console.log('Això SEMPRE es mostra, encara que la llista sigui buida');
}

if (etiquetes.length === 0) {
  console.log('Així sí que es detecta una llista buida'); // ← correcte
}

  1. Conversió implícita (coerció)

Ara que saps convertir tu, vegem quan ho fa JavaScript pel seu compte.

5.1 Coerció a text: el +

Si algun dels operands de + és un string, l'altre es converteix a string.

console.log('Hores: ' + 12);     // 'Hores: 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ó a nombre: la resta d'operadors aritmètics

-, *, /, % i ** sempre converteixen a nombre:

console.log('12' - 4);      // 8
console.log('12' * '2');    // 24
console.log(true + 1);      // 2      ← true es converteix en 1
console.log(false + 1);     // 1      ← false es converteix en 0
console.log(null + 5);      // 5      ← null es converteix en 0
console.log(undefined + 5); // NaN    ← undefined es converteix en NaN
console.log([] + 1);        // '1'    ← l'array buit es converteix a ''
console.log([5] * 2);       // 10     ← [5] es converteix a '5' i després a 5

Les quatre últimes línies són el tipus de raresa que fa famós JavaScript. No les memoritzis: memoritza la conclusió, que és no barrejar tipus.

5.3 El cas que trenca càlculs reals

Aquest és l'error pràctic que et trobaràs de debò:

// Dades que arriben d'un formulari: SEMPRE són text
const horesTasca1 = '12';
const horesTasca2 = '8';

console.log(horesTasca1 + horesTasca2);  // '128'  ← malament!

// Convertint abans d'operar
console.log(Number(horesTasca1) + Number(horesTasca2)); // 20 ← correcte

I el que passa quan només un dels valors és text:

const horesIvan = 12;         // nombre
const horesLucia = '8';       // text (ve d'un input)

console.log(horesIvan + horesLucia);   // '128'  ← concatena
console.log(horesIvan - horesLucia);   // 4      ← resta bé
console.log(horesIvan * horesLucia);   // 96     ← multiplica bé

Que uns operadors funcionin i d'altres no és el que fa tan difícil de localitzar aquesta fallada: el programa sembla que funciona fins que arriba a una suma.

  1. Operadors de comparació

Els operadors relacionals retornen sempre un booleà:

Operador Nom Exemple Resultat
> Més gran que 12 > 8 true
< Més petit que 12 < 8 false
>= Més gran o igual 12 >= 12 true
<= Més petit o igual 8 <= 12 true
== Igualtat laxa '12' == 12 true
=== Igualtat estricta '12' === 12 false
!= Desigualtat laxa '12' != 12 false
!== Desigualtat estricta '12' !== 12 true
const horesEstimades = 12;
const MAX_HORES_DIA = 8;

console.log(horesEstimades > MAX_HORES_DIA);  // true
console.log(horesEstimades <= MAX_HORES_DIA); // false

  1. == enfront de ===

Aquí hi ha el cor de la lliçó.

  • === (igualtat estricta) compara valor i tipus. Si els tipus difereixen, retorna false sense més.
  • == (igualtat laxa) converteix els valors a un tipus comú abans de comparar.
console.log('12' === 12);  // false ← tipus diferents
console.log('12' == 12);   // true  ← converteix '12' a 12 i compara

7.1 Els casos clàssics de ==

Comparació == === Per què
'5' == 5 true false El text es converteix a nombre
'' == 0 true false La cadena buida es converteix a 0
'0' == 0 true false '0' es converteix a 0
'' == '0' false false Tots dos són text: es comparen tal qual
false == 0 true false false es converteix a 0
false == '' true false Tots dos es converteixen a 0
null == undefined true false Regla especial del llenguatge
null == 0 false false null només és laxament igual a undefined
NaN == NaN false false NaN no és mai igual a res, ni a si mateix
[] == false true false []''0, i false0
[] == '' true false L'array buit es converteix a cadena buida

Fixa't en la incoherència demolidora: '' == 0 és true i '0' == 0 és true, però '' == '0' és false. És a dir, == no és transitiu. Dos valors poden ser "iguals" a un tercer i no ser-ho entre ells. Això tot sol ja hauria de bastar per desterrar == del teu codi.

7.2 L'única excepció tolerada

Hi ha un ús de == que molts equips accepten: comprovar d'un sol cop si un valor és null o undefined.

const revisor = null;

// Amb == cobreix els dos casos alhora
if (revisor == null) {
  console.log('Sense revisor assignat');
}

// Equivalent estricte, més explícit
if (revisor === null || revisor === undefined) {
  console.log('Sense revisor assignat');
}

Tot i així, avui existeix una alternativa més neta amb ??, que ja coneixes:

const nomRevisor = revisor ?? 'Sense revisor assignat';

7.3 El cas de NaN

NaN és l'únic valor de JavaScript que no és igual a si mateix, ni amb == ni amb ===:

console.log(NaN === NaN); // false
console.log(NaN == NaN);  // false

Per això existeix Number.isNaN():

const hores = Number('dotze'); // NaN
console.log(Number.isNaN(hores)); // true

Compte amb la funció global antiga isNaN(), que converteix abans de comprovar i dona falsos positius:

console.log(isNaN('alta'));        // true  ← converteix 'alta' a NaN primer
console.log(Number.isNaN('alta')); // false ← 'alta' és un string, no NaN

Fes servir sempre Number.isNaN().

  1. Comparar cadenes i comparar nombres

Els operadors < i > es comporten de manera diferent segons els tipus.

Si tots dos són text, es comparen caràcter a caràcter segons el seu codi Unicode (aproximadament, ordre alfabètic):

console.log('alta' < 'baixa');  // true  ← 'a' va abans que 'b'
console.log('Iván' < 'iván');   // true  ← les majúscules van abans
console.log('10' < '9');        // true  ← comparació de TEXT! '1' < '9'

Aquesta última línia és un parany clàssic: com a text, '10' és més petit que '9' perquè es compara el primer caràcter.

Si algun és nombre, tots dos es converteixen a nombre:

console.log(10 < 9);      // false
console.log('10' < 9);    // false ← '10' es converteix a 10

Per ordenar textos amb criteri d'idioma (accents, dígrafs) existeix localeCompare:

console.log('òliba'.localeCompare('ovella', 'ca')); // -1 → 'òliba' va abans

8.1 Per què les dates ISO són tan còmodes

Aquí es veu per què a Nómada Tasques desem les dates com a text 'yyyy-mm-dd':

const data1 = '2026-09-30';
const data2 = '2026-11-05';

console.log(data1 < data2); // true — ordre cronològic correcte

El format ISO té la propietat que el seu ordre alfabètic coincideix amb el seu ordre cronològic, perquè els components van de més a menys magnitud i amb zeros a l'esquerra. Amb '30/09/2026' això no funcionaria de cap manera.

  1. Comparar objectes: el parany de la referència

Recorda de la lliçó de tipus: els objectes i arrays es manegen per referència. En comparar-los, JavaScript no mira el contingut: mira si són el mateix objecte a la memòria.

const etiquetes1 = ['disseny', 'espai'];
const etiquetes2 = ['disseny', 'espai'];

console.log(etiquetes1 === etiquetes2); // false ← contingut igual, objectes diferents
console.log(etiquetes1 == etiquetes2);  // false ← == tampoc no ajuda

const etiquetes3 = etiquetes1;
console.log(etiquetes1 === etiquetes3); // true ← és el mateix objecte

El mateix amb objectes:

const tascaA = { id: 1, titol: 'Revisar factures' };
const tascaB = { id: 1, titol: 'Revisar factures' };

console.log(tascaA === tascaB);       // false
console.log(tascaA.id === tascaB.id); // true ← comparant primitius, sí
flowchart TD
    A["etiquetes1"] --> M1["Memòria: ['disseny','espai']"]
    B["etiquetes2"] --> M2["Memòria: ['disseny','espai']"]
    C["etiquetes3"] --> M1
    M1 -.->|"=== M2"| R["false: són<br/>zones diferents"]

Regla pràctica: per comparar dues tasques, compara'n els camps (normalment l'id), mai els objectes sencers amb ===. Les tècniques per comparar continguts es veuen a JSON i Còpies d'Objectes.

  1. Object.is i els casos límit

Object.is() (ES2015) es comporta com === llevat de dos casos on === té un comportament discutible:

console.log(NaN === NaN);          // false
console.log(Object.is(NaN, NaN));  // true  ← més raonable

console.log(0 === -0);             // true
console.log(Object.is(0, -0));     // false ← distingeix el zero negatiu
Comparació == === Object.is
'12' i 12 true false false
null i undefined true false false
NaN i NaN false false true
0 i -0 true true false
'alta' i 'alta' true true true

En el dia a dia faràs servir ===. Object.is és útil quan t'importi distingir NaN o el zero negatiu, situacions poc freqüents però reals en càlculs numèrics.

  1. Regles pràctiques d'higiene

Cinc regles que t'estalviaran la major part dels problemes d'aquesta lliçó:

  1. Fes servir sempre === i !==. Sense excepcions mentre aprens. Les eines de qualitat de codi que veuràs al Mòdul 8 t'avisaran si se t'escapa un ==.
  2. Converteix explícitament abans d'operar. Si una dada pot ser text, aplica-li Number() abans de sumar-la. No confiïs en la coerció.
  3. No barregis tipus en una mateixa variable. Si hores és un nombre, que sigui sempre un nombre.
  4. Comprova l'absència de valor explícitament. if (valor === null) o valor ?? defecte, en lloc de confiar en truthy/falsy.
  5. Compte amb 0, '' i []. Els dos primers són falsy encara que siguin dades vàlides; el tercer és truthy encara que estigui buit.
flowchart TD
    A["Reps una dada"] --> B{"D'on<br/>ve?"}
    B -->|"Formulari, URL,<br/>emmagatzematge"| C["És TEXT,<br/>sempre"]
    B -->|"El teu propi codi"| D["Ja té el<br/>tipus correcte"]
    C --> E["Converteix amb<br/>Number() o String()"]
    E --> F["Valida amb<br/>Number.isNaN() i trim()"]
    F --> G["Compara amb ==="]
    D --> G

  1. Aplicació: validar les dades d'un formulari de tasca

La Marta omple un formulari per donar d'alta una tasca a Nómada Tasques. Els camps d'un formulari web retornen sempre text, fins i tot els numèrics i els de data. Comprovem les dades abans de fer-les servir.

'use strict';

// --- Dades tal com arriben d'un formulari: TOT són strings ---------
const idText = '5';
const titolText = '  Preparar el taller de serigrafia  ';
const responsableText = '';           // no s'ha omplert
const prioritatText = 'mitjana';
const horesText = '6';
const dataLimitText = '2026-10-15';
const etiquetesText = 'taller, formació';

// --- Conversió explícita ------------------------------------------
const id = Number(idText);
const titol = titolText.trim();       // treu els espais sobrants
const horesEstimades = Number(horesText);

// --- Validacions ---------------------------------------------------

// 1. L'id ha de ser un nombre vàlid i positiu
const idEsValid = !Number.isNaN(id) && id > 0;

// 2. El títol no pot estar buit un cop retallat
const titolEsValid = titol !== '';

// 3. Les hores: nombre vàlid, més gran que 0. Compte: Number('') és 0
const horesSonValides =
  horesText.trim() !== '' && !Number.isNaN(horesEstimades) && horesEstimades > 0;

// 4. La prioritat ha de ser un dels tres valors permesos
const prioritatEsValida =
  prioritatText === 'alta' ||
  prioritatText === 'mitjana' ||
  prioritatText === 'baixa';

// 5. La data ISO té sempre 10 caràcters i no pot ser passada
const AVUI = '2026-08-18';
const dataEsValida =
  dataLimitText.length === 10 && dataLimitText >= AVUI;

// 6. El responsable pot faltar: fem servir null a propòsit
const responsable = responsableText.trim() === '' ? null : responsableText.trim();

// 7. Les etiquetes: si el text és buit, llista buida
//    split(', ') parteix el text pel separador i retorna un array
const etiquetes =
  etiquetesText.trim() === '' ? [] : etiquetesText.split(', ');

// --- Resultat global -----------------------------------------------
const formulariEsValid =
  idEsValid && titolEsValid && horesSonValides &&
  prioritatEsValida && dataEsValida;

// --- Sortida -------------------------------------------------------
console.log('=== Validació de la tasca ===');
console.log(`id (${typeof id}):             ${id}  → ${idEsValid ? 'OK' : 'ERROR'}`);
console.log(`títol:                         "${titol}" → ${titolEsValid ? 'OK' : 'ERROR'}`);
console.log(`hores (${typeof horesEstimades}):          ${horesEstimades} → ${horesSonValides ? 'OK' : 'ERROR'}`);
console.log(`prioritat:                     ${prioritatText} → ${prioritatEsValida ? 'OK' : 'ERROR'}`);
console.log(`data límit:                    ${dataLimitText} → ${dataEsValida ? 'OK' : 'ERROR'}`);
console.log(`responsable:                   ${responsable ?? 'Sense assignar'}`);
console.log(`etiquetes (${etiquetes.length}):                 ${etiquetes.join(' · ')}`);
console.log(`\nFormulari vàlid: ${formulariEsValid ? 'SÍ' : 'NO'}`);

Sortida:

=== Validació de la tasca ===
id (number):             5  → OK
títol:                         "Preparar el taller de serigrafia" → OK
hores (number):          6 → OK
prioritat:                     mitjana → OK
data límit:                    2026-10-15 → OK
responsable:                   Sense assignar
etiquetes (2):                 taller · formació

Formulari vàlid: SÍ

Decisions importants d'aquest codi:

  • Tot es converteix explícitament. Number(idText) i Number(horesText) en lloc de confiar que el + es porti bé.
  • .trim() abans de validar textos. Un títol de només espais passaria una comprovació ingènua.
  • La doble comprovació d'hores. horesText.trim() !== '' és imprescindible perquè Number('') retorna 0, no NaN. Sense ella, un camp buit passaria com a "0 hores".
  • === en totes les comparacions. La prioritat es compara amb els tres valors exactes.
  • La data es compara com a text aprofitant el format ISO. '2026-10-15' >= '2026-08-18' és true.
  • El responsable absent és null, no ''. Estem afirmant "no hi ha responsable", no desant un text buit.
  • Les etiquetes absents són [], no null. Una llista buida continua sent una llista, i així tot el codi posterior pot tractar-la igual.

La validació des del punt de vista de la interfície —llegir el formulari real, mostrar missatges d'error al costat de cada camp, impedir l'enviament— és matèria de Gestió i Validació de Formularis. Aquí ens hem centrat en la lògica de conversió i comparació, que és la part que de debò decideix si una dada és correcta.

Errors Habituals i Consells

Errors habituals

  • Fer servir == per costum. Genera errors que apareixen mesos després amb dades concretes. Fes servir ===.
  • Oblidar que Number('') és 0. Un camp buit passa com a zero hores i ningú no se n'assabenta.
  • Confiar en if (valor) per a nombres. Si valor és 0, la condició no es compleix encara que la dada sigui legítima.
  • Comprovar si un array és buit amb if (!llista). Un array buit és truthy. Fes servir llista.length === 0.
  • Comparar NaN amb ===. No funciona mai. Fes servir Number.isNaN().
  • Fer servir la funció global isNaN(). Converteix abans de comprovar i dona falsos positius. Fes servir Number.isNaN().
  • Comparar objectes o arrays amb === esperant comparar-ne el contingut. Compara referències. Compara'n els camps.
  • Cridar .toString() sobre una cosa que pot ser null. TypeError garantit. Fes servir String().
  • Comparar nombres desats com a text amb < o >. '10' < '9' és true. Converteix abans.
  • Sumar directament valors d'un formulari. '12' + '8' és '128'.

Consells

  • Converteix a la frontera. Tan bon punt una dada entra al teu programa (formulari, URL, emmagatzematge), converteix-la al tipus correcte. A partir d'aquí, tot el codi hi pot confiar.
  • Memoritza els vuit valors falsy. És la taula que més rendibilitat et donarà de tot el mòdul.
  • Quan alguna cosa es comporti de manera estranya, imprimeix typeof. console.log(typeof x, x) resol la meitat dels misteris en dos segons.
  • Dona nom a les validacions: const horesSonValides = .... Un if amb cinc condicions sense nom és il·legible.
  • Fes servir dates ISO 'yyyy-mm-dd' i les podràs comparar i ordenar com a text sense cap llibreria.
  • Number() per validar, parseInt/parseFloat per extreure.

Exercicis

Exercici 1: Prediu les conversions

Escriu el resultat de cada línia:

console.log(Number('  25  '));      // A
console.log(Number(''));            // B
console.log(Number('25 hores'));    // C
console.log(parseInt('25 hores'));  // 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));           // L

Exercici 2: == enfront de ===

Omple la taula indicant el resultat de cada comparació amb els dos operadors, i explica els tres casos que et semblin més sorprenents:

Comparació == ===
'6' ? 6
'' ? 0
'' ? '0'
null ? undefined
null ? 0
false ? 0
NaN ? NaN
'alta' ? 'alta'

Exercici 3: Validador d'hores d'una tasca

Escriu un script que validi el camp "hores estimades" d'un formulari de Nómada Tasques. Ha de comprovar, per a cada valor d'entrada, que:

  • No està buit ni conté només espais.
  • És un nombre vàlid.
  • És més gran que 0.
  • No supera les 40 hores (una setmana completa).

Per a cada entrada, imprimeix el valor original, el valor convertit i el resultat (OK o el motiu de l'error).

Prova amb aquestes entrades: '8', '0', '', ' ', 'vuit', '7.5', '45', '8 hores'.

Solucions

Exercici 1

Línia Resultat Explicació
A 25 Number() ignora els espais del voltant
B 0 La cadena buida es converteix a 0, no a NaN
C NaN Number() exigeix que tot el text sigui numèric
D 25 parseInt llegeix des del principi i s'atura a l'espai
E 7.5 parseFloat conserva decimals i s'atura a la h
F 0 null es converteix numèricament a 0
G NaN undefined no té equivalent numèric
H 'null' String() funciona amb null (a diferència de .toString())
I true El text '0' no és la cadena buida, així que és truthy
J true Un array buit és un objecte, i tots els objectes són truthy
K false La cadena buida és a la llista de falsy
L true Només el 0 és falsy; qualsevol altre nombre és truthy

Exercici 2

Comparació == ===
'6' i 6 true false
'' i 0 true false
'' i '0' false false
null i undefined true false
null i 0 false false
false i 0 true false
NaN i NaN false false
'alta' i 'alta' true true

Els tres casos més sorprenents:

  1. '' == 0 és true però '' == '0' és false. Quan els dos operands són text, == no converteix res i els compara tal qual. Això demostra que == no és transitiu: '' és "igual" a 0 i '0' és "igual" a 0, però '' i '0' no són iguals entre ells.
  2. null == undefined és true però null == 0 és false. No hi ha cap lògica de conversió al darrere: és una regla especial escrita explícitament a l'especificació. null només és laxament igual a undefined i a si mateix.
  3. NaN == NaN és false. L'únic valor del llenguatge que no és igual a si mateix, seguint l'estàndard IEEE 754 de coma flotant. Per això existeix Number.isNaN().

Exercici 3

'use strict';

// --- Constants de negoci -------------------------------------------
const MIN_HORES = 0;
const MAX_HORES = 40;

// --- Entrades a provar ---------------------------------------------
const entrada = '8'; // canvia-la per provar les altres

// --- Validació pas a pas -------------------------------------------
const retallada = entrada.trim();
const hores = Number(retallada);

// Ternari encadenat: l'ordre de les comprovacions és deliberat
const resultat =
  retallada === ''      ? 'ERROR: el camp és buit' :
  Number.isNaN(hores)   ? 'ERROR: no és un nombre vàlid' :
  hores <= MIN_HORES    ? 'ERROR: ha de ser més gran que 0' :
  hores > MAX_HORES     ? `ERROR: no pot superar ${MAX_HORES} hores` :
                          'OK';

console.log(`"${entrada}" → ${hores} (${typeof hores}) → ${resultat}`);

Resultats esperats per a totes les entrades:

Entrada trim() Number() Resultat
'8' '8' 8 OK
'0' '0' 0 ERROR: ha de ser més gran que 0
'' '' 0 ERROR: el camp és buit
' ' '' 0 ERROR: el camp és buit
'vuit' 'vuit' NaN ERROR: no és un nombre vàlid
'7.5' '7.5' 7.5 OK
'45' '45' 45 ERROR: no pot superar 40 hores
'8 hores' '8 hores' NaN ERROR: no és un nombre vàlid

Tres observacions clau:

  • L'ordre de les comprovacions importa. La de cadena buida va primer, perquè Number('') dona 0 i aquesta entrada acabaria donant el missatge "ha de ser més gran que 0", que és confús i no descriu el problema real.
  • ' ' i '' produeixen el mateix error gràcies al .trim() previ.
  • '8 hores' es rebutja perquè hem fet servir Number(). Si haguéssim fet servir parseInt, hauria passat com a 8 en silenci. En una validació d'entrada això seria un error: Number() és l'elecció correcta per validar.

Conclusió

Has desbrossat el terreny on més s'ensopega en JavaScript. Saps convertir explícitament amb Number(), parseInt(), parseFloat(), String(), .toString() i Boolean(), i coneixes els paranys de cadascun (Number('') és 0, .toString() falla amb null). Domines la conversió implícita: el + concatena si hi ha un string, la resta d'operadors aritmètics converteixen a nombre. Et saps la llista completa dels vuit valors falsy i recordes que '0' i [] són truthy. Distingeixes == de === i has vist per què la igualtat laxa ni tan sols és transitiva. Saps que les cadenes es comparen alfabèticament —i per què això fa tan còmodes les dates ISO—, que els objectes es comparen per referència, i que existeix Object.is per als casos límit de NaN i -0.

I el més pràctic: has escrit un validador complet per a les dades d'un formulari de tasca de Nómada Tasques, aquelles que arriben sempre com a text.

Amb això tanques la caixa d'eines bàsica: entorn, sintaxi, variables, tipus, operadors i comparacions. Ja tens tot el que cal per entendre el projecte en conjunt. A l'última lliçó del mòdul, El Projecte del Curs: Nómada Tasques, coneixeràs a fons Taller Nómada i el seu problema, el model de dades canònic d'una tasca amb tots els seus camps i valors permesos, i el mapa complet del que construiràs a cada mòdul del curs.

Curs de JavaScript: De Principiant a Avançat

Mòdul 1: Introducció a JavaScript

Mòdul 2: Estructures de Control

Mòdul 3: Funcions

Mòdul 4: Objectes i Arrays

Mòdul 5: Objectes i Funcions Avançades

Mòdul 6: El Model d'Objectes del Document (DOM)

Mòdul 7: APIs del Navegador i Temes Avançats

Mòdul 8: Proves i Depuració

Mòdul 9: Rendiment i Optimització

Mòdul 10: Frameworks i Llibreries de JavaScript

Mòdul 11: Projecte Final

© Copyright 2026. Tots els drets reservats