A la lliçó anterior vas aprendre a desar les dades d'una tasca de Taller Nómada en variables del tipus adequat. Desar està bé, però un programa que no calcula res serveix de poc. Els operadors són els símbols que combinen i transformen valors: sumar hores, calcular percentatges, decidir si una condició es compleix o proporcionar un valor per defecte quan falta una dada. En aquesta lliçó els recorreràs tots —des de l'humil + fins als moderns ?? i ?.— i acabaràs calculant la càrrega de treball real de la Marta, l'Iván i la Lucía.

Contingut

  1. Operadors aritmètics
  2. Increment i decrement: prefix i sufix
  3. Operadors d'assignació
  4. Operadors lògics i curtcircuit
  5. Coalescència nul·la: ?? i ??=
  6. Encadenament opcional: ?.
  7. L'operador ternari ? :
  8. Concatenació enfront de template literals
  9. Precedència d'operadors
  10. Aplicació: la càrrega d'hores de l'equip
  11. Errors Habituals i Consells
  12. Exercicis
  13. Conclusió

  1. Operadors aritmètics

Són els que fan càlculs numèrics.

Operador Nom Exemple Resultat
+ Suma 12 + 8 20
- Resta 12 - 8 4
* Multiplicació 12 * 2 24
/ Divisió 12 / 8 1.5
% Mòdul (residu) 12 % 8 4
** Exponenciació 2 ** 3 8
const horesIvan = 12;
const horesLucia = 8;

console.log(horesIvan + horesLucia);  // 20
console.log(horesIvan - horesLucia);  // 4
console.log(horesIvan / horesLucia);  // 1.5
console.log(horesIvan % horesLucia);  // 4

1.1 El mòdul % és més útil del que sembla

% retorna el residu d'una divisió entera. Els seus dos usos clàssics:

Saber si un nombre és parell o senar:

const numeroTasca = 7;
console.log(numeroTasca % 2);        // 1 → senar
console.log(numeroTasca % 2 === 0);  // false

Repartir en cicles. A Nómada Tasques el farem servir per assignar tasques rotant entre les tres persones de l'equip:

// L'equip té 3 persones: posicions 0, 1 i 2
console.log(0 % 3); // 0 → Marta
console.log(1 % 3); // 1 → Iván
console.log(2 % 3); // 2 → Lucía
console.log(3 % 3); // 0 → Marta un altre cop
console.log(4 % 3); // 1 → Iván

El residu de dividir entre 3 sempre dona 0, 1 o 2: exactament les posicions de l'equip, cíclicament.

1.2 La divisió no falla mai

En molts llenguatges dividir entre zero provoca un error. En JavaScript, no:

console.log(12 / 0);   // Infinity
console.log(-12 / 0);  // -Infinity
console.log(0 / 0);    // NaN

Això és perillós perquè el programa no s'atura: continua calculant amb Infinity o NaN i l'error apareix molt més tard, en un lloc que no hi té res a veure.

const tasquesCompletades = 5;
const tasquesTotals = 0; // encara no hi ha tasques!

const percentatge = (tasquesCompletades / tasquesTotals) * 100;
console.log(percentatge); // Infinity — no és un error, però està malament

La solució és comprovar el divisor abans de dividir, cosa que faràs còmodament quan aprenguis condicionals al Mòdul 2.

1.3 El + té doble personalitat

Aquí arriba el primer gran parany. + és alhora suma i concatenació de textos:

console.log(12 + 8);      // 20    → suma numèrica
console.log('12' + '8');  // '128' → concatenació de textos
console.log('12' + 8);    // '128' → si un és text, concatena!
console.log(12 + '8');    // '128'

La regla és implacable: si algun dels dos operands és un string, + concatena. Aquest comportament és la causa número u dels càlculs incorrectes en principiants, sobretot amb dades que vénen d'un formulari (on tot arriba com a text).

La resta d'operadors aritmètics no tenen aquest problema: intenten convertir a nombre.

console.log('12' - 8);   // 4  → converteix '12' a nombre
console.log('12' * 2);   // 24
console.log('12' / 2);   // 6
console.log('alta' * 2); // NaN → no es pot convertir

A Conversió de Tipus i Comparacions veuràs exactament per què passa això i com protegir-te'n.

  1. Increment i decrement: prefix i sufix

++ suma 1 i -- resta 1 a una variable.

let tasquesCompletades = 5;

tasquesCompletades++;
console.log(tasquesCompletades); // 6

tasquesCompletades--;
console.log(tasquesCompletades); // 5

Tots dos tenen dues formes, i la diferència importa només quan fas servir el resultat en la mateixa expressió:

Forma Nom Què fa
x++ Sufixa (postfixa) Retorna el valor antic i després incrementa
++x Prefixa Incrementa i després retorna el valor nou
let a = 5;
console.log(a++); // 5 ← retorna el valor antic
console.log(a);   // 6 ← però ja està incrementada

let b = 5;
console.log(++b); // 6 ← incrementa primer
console.log(b);   // 6

Mnemotècnia: el ++ s'executa a la posició on està escrit. Si va davant, primer incrementa; si va darrere, primer retorna.

Consell pràctic: fes servir ++ i -- en línies soltes, mai dins d'expressions complexes. Aquest tipus de codi és una font inesgotable d'errors:

let i = 5;
const resultat = i++ + ++i; // 5 + 7 = 12. Il·legible. No ho escriguis.

  1. Operadors d'assignació

= assigna un valor. La resta combinen una operació amb l'assignació:

Operador Equival a Exemple Resultat (partint de h = 12)
= h = 8 8
+= h = h + 8 h += 8 20
-= h = h - 8 h -= 8 4
*= h = h * 2 h *= 2 24
/= h = h / 4 h /= 4 3
%= h = h % 5 h %= 5 2
**= h = h ** 2 h **= 2 144
let horesAcumulades = 0;

horesAcumulades += 12; // tasca de l'Iván
horesAcumulades += 8;  // tasca de la Lucía
horesAcumulades += 6;  // tasca de la Marta

console.log(horesAcumulades); // 26

+= també funciona amb textos, i per la mateixa raó que +:

let resum = 'Equip: ';
resum += 'Marta, ';
resum += 'Iván, ';
resum += 'Lucía';
console.log(resum); // Equip: Marta, Iván, Lucía

Recorda que les variables assignades amb aquests operadors s'han de declarar amb let: amb const obtindries un TypeError.

  1. Operadors lògics i curtcircuit

Són tres, i amaguen un comportament que convé entendre bé.

Operador Nom Significat informal
&& I lògic (AND) Tots dos s'han de complir
|| O lògic (OR) N'hi ha prou que se'n compleixi un
! Negació (NOT) Inverteix el valor lògic
const esUrgent = true;
const estaAssignada = false;

console.log(esUrgent && estaAssignada); // false
console.log(esUrgent || estaAssignada); // true
console.log(!esUrgent);                 // false

4.1 L'avaluació de curtcircuit

JavaScript avalua aquests operadors d'esquerra a dreta i s'atura tan bon punt coneix el resultat:

  • Amb &&: si el primer valor és fals, el resultat ja és fals. No avalua el segon.
  • Amb ||: si el primer valor és cert, el resultat ja és cert. No avalua el segon.
function avisar() {
  console.log('Avís enviat a la Marta');
  return true;
}

false && avisar(); // No imprimeix res: s'atura al false
true || avisar();  // No imprimeix res: s'atura al true
true && avisar();  // Imprimeix 'Avís enviat a la Marta'

Això es fa servir moltíssim com a drecera per a "fes això només si allò es compleix":

const esUrgent = true;
esUrgent && console.log("Avisar l'equip de Taller Nómada");

4.2 El que retornen realment

Aquí hi ha el detall que gairebé ningú no explica: && i || no retornen true o false. Retornen un dels operands.

  • a || b retorna a si a és truthy; si no, retorna b.
  • a && b retorna a si a és falsy; si no, retorna b.
console.log('Iván' || 'sense assignar');  // 'Iván'
console.log('' || 'sense assignar');      // 'sense assignar'
console.log(0 || 40);                     // 40
console.log('alta' && 'mitjana');         // 'mitjana'
console.log(null && 'mitjana');           // null

(Els conceptes truthy i falsy —quins valors es consideren certs o falsos sense ser-ho— es detallen a la lliçó vinent. Per ara n'hi ha prou de saber que 0, '', null, undefined i NaN són falsy, i pràcticament tota la resta és truthy.)

Aquest comportament habilita el patró clàssic del valor per defecte:

const responsableRebut = '';
const responsable = responsableRebut || 'Sense assignar';
console.log(responsable); // 'Sense assignar'

Però compte: té un parany important.

const horesRebudes = 0; // 0 és un valor legítim!
const hores = horesRebudes || 8;
console.log(hores); // 8 ← malament! Volíem 0

Com que 0 és falsy, || el descarta. Per resoldre exactament això es va crear ??.

4.3 L'operador ! i el doble !!

! inverteix el valor lògic:

const estaFeta = false;
console.log(!estaFeta); // true

Aplicat dues vegades, !! converteix qualsevol valor al seu equivalent booleà:

console.log(!!'Iván');   // true
console.log(!!'');       // false
console.log(!!0);        // false
console.log(!!12);       // true
console.log(!!null);     // false

És un truc molt estès, tot i que Boolean(valor) expressa el mateix amb més claredat.

  1. Coalescència nul·la: ?? i ??=

L'operador ?? (ES2020) retorna l'operand dret només si l'esquerre és null o undefined. A diferència de ||, respecta el 0, l''' i el false.

const horesRebudes = 0;

console.log(horesRebudes || 8); // 8  ← || descarta el 0
console.log(horesRebudes ?? 8); // 0  ← ?? el respecta

Comparativa completa:

Valor esquerre valor || 'defecte' valor ?? 'defecte'
'Iván' 'Iván' 'Iván'
'' 'defecte' ''
0 'defecte' 0
false 'defecte' false
NaN 'defecte' NaN
null 'defecte' 'defecte'
undefined 'defecte' 'defecte'

Regla pràctica: per a valors per defecte, fes servir ??. Fes servir || només quan vulguis tractar també el 0 i la cadena buida com a "absència de valor" a propòsit.

flowchart TD
    A["Necessites un<br/>valor per defecte"] --> B{"El 0, el false<br/>i la cadena buida<br/>són dades vàlides?"}
    B -->|"Sí (hores, comptadors)"| C["Fes servir ??<br/>només actua davant<br/>de null i undefined"]
    B -->|"No (noms, textos)"| D["Pots fer servir ||<br/>actua davant de qualsevol<br/>valor falsy"]
    C --> E["horesEstimades ?? 8"]
    D --> F["responsable || 'Sense assignar'"]
const responsable = null;
const horesEstimades = 0;

console.log(responsable ?? 'Sense assignar'); // 'Sense assignar'
console.log(horesEstimades ?? 8);             // 0 — correcte

5.1 Assignació amb ??=

??= assigna un valor només si la variable és null o undefined:

let revisor = null;
revisor ??= 'Marta';
console.log(revisor); // 'Marta'

let responsable = 'Lucía';
responsable ??= 'Marta';
console.log(responsable); // 'Lucía' — no es toca

Equival a if (revisor === null || revisor === undefined) { revisor = 'Marta'; }, però en una línia.

També existeixen ||= i &&= amb la mateixa lògica aplicada a truthy/falsy.

5.2 Una restricció de sintaxi

No pots barrejar ?? amb && o || sense parèntesis: és un SyntaxError deliberat, per evitar ambigüitats.

// const x = a || b ?? c;    // SyntaxError
const x = (a || b) ?? c;     // Correcte: els parèntesis aclareixen la intenció

  1. Encadenament opcional: ?.

L'operador ?. (ES2020) accedeix a una propietat només si el valor anterior no és null ni undefined. Si ho és, retorna undefined en lloc de llançar un error.

El problema que resol:

const tasca = { titol: 'Redissenyar la sala', responsable: null };

// console.log(tasca.responsable.length); // TypeError: Cannot read properties of null

Aquest TypeError atura el programa sencer. Amb ?.:

console.log(tasca.responsable?.length); // undefined — sense error

Es pot encadenar tantes vegades com calgui:

const tasca = { titol: 'Muntar una exposició' };

console.log(tasca.revisio?.autor);      // undefined
console.log(tasca.revisio?.autor?.nom); // undefined

Sense ?., la segona línia llançaria un TypeError tan bon punt tasca.revisio fos undefined.

Es combina de meravella amb ??:

const tasca = { titol: 'Revisar factures', responsable: null };
const nom = tasca.responsable?.nom ?? 'Sense assignar';
console.log(nom); // 'Sense assignar'

Avís important: ?. no és una excusa per no comprovar les dades. Si el poses a tot arreu, amagaràs errors reals en lloc de resoldre'ls. Fes-lo servir on de debò sigui legítim que el valor falti.

L'ús complet de ?. amb objectes imbricats, arrays (tasca?.etiquetes?.[0]) i crides a funcions (tasca.desar?.()) es reprendrà al Mòdul 4, quan treballis amb objectes de debò.

  1. L'operador ternari ? :

És l'únic operador de JavaScript que pren tres operands. La seva forma:

condicio ? valorSiCert : valorSiFals
const horesEstimades = 12;
const tipusTasca = horesEstimades > 8 ? 'llarga' : 'curta';
console.log(tipusTasca); // 'llarga'

Es llegeix com una pregunta: horesEstimades > 8? Doncs 'llarga'; si no, 'curta'.

El gran avantatge davant d'un if és que el ternari és una expressió: produeix un valor i per tant es pot assignar, passar com a argument o interpolar.

const responsable = 'Marta';
const hores = 6;

console.log(`${responsable} té una tasca ${hores > 8 ? 'llarga' : 'curta'}`);
// Marta té una tasca curta

Es poden encadenar, tot i que convé no abusar-ne:

const horesEstimades = 12;

const categoria =
  horesEstimades > 16 ? 'projecte' :
  horesEstimades > 8  ? 'llarga' :
  horesEstimades > 2  ? 'mitjana' :
                        'ràpida';

console.log(categoria); // 'llarga'

Alineat així es llegeix bé, però a partir de tres o quatre casos és millor un switch o un if/else, que veuràs al Mòdul 2.

Quan fer servir cadascun:

Situació Eina
Triar entre dos valors per assignar-los Ternari
Inserir una decisió dins d'un text Ternari
Executar diverses sentències segons la condició if/else
Molts casos sobre el mateix valor switch

  1. Concatenació enfront de template literals

Ja coneixes les dues maneres de compondre text. Comparem-les de front:

const responsable = 'Iván';
const hores = 12;
const dataLimit = '2026-09-30';

// Concatenació amb +
const ambConcatenacio =
  'Tasca de ' + responsable + ': ' + hores + ' h, venç el ' + dataLimit;

// Template literal
const ambPlantilla =
  `Tasca de ${responsable}: ${hores} h, venç el ${dataLimit}`;
Aspecte Concatenació + Template literal
Llegibilitat Baixa: el text es trenca Alta: el text es llegeix sencer
Espais Fàcils d'oblidar Es veuen al text mateix
Expressions Requereixen parèntesis ${hores * 2} directament
Salts de línia Amb \n Reals, prement Retorn
Risc de concatenar sense voler Alt Nul: tot es converteix a text

Aquest últim punt és important. Amb + pots acabar sumant per accident:

const horesIvan = 12;
const horesLucia = 8;

console.log('Total: ' + horesIvan + horesLucia);   // 'Total: 128' ← malament!
console.log('Total: ' + (horesIvan + horesLucia)); // 'Total: 20'  ← amb parèntesis
console.log(`Total: ${horesIvan + horesLucia}`);   // 'Total: 20'  ← sense ambigüitat

Fes servir template literals sempre que combinis text i variables. No hi ha cap motiu per no fer-ho.

  1. Precedència d'operadors

Quan una expressió barreja operadors, JavaScript aplica un ordre fix anomenat precedència. De més a menys prioritat, pel que t'afecta ara:

Nivell Operadors Associativitat Exemple
1 () agrupació (2 + 3) * 420
2 ?. accés opcional Esquerra tasca?.titol
3 ++ -- sufixos i++
4 ! ++ -- prefixos, typeof Dreta !estaFeta
5 ** Dreta 2 ** 3 ** 2512
6 * / % Esquerra 2 + 3 * 414
7 + - Esquerra 10 - 3 - 25
8 < > <= >= Esquerra 12 > 8
9 == != === !== Esquerra 'alta' === 'alta'
10 && Esquerra a && b
11 || i ?? Esquerra a || b
12 ? : ternari Dreta x > 0 ? 'sí' : 'no'
13 = += -= ??= Dreta x += 1

Exemples que aclareixen les regles:

console.log(2 + 3 * 4);        // 14, no 20: * té més precedència que +
console.log((2 + 3) * 4);      // 20: els parèntesis manen
console.log(10 - 3 - 2);       // 5: - és associatiu per l'esquerra → (10-3)-2
console.log(2 ** 3 ** 2);      // 512: ** és associatiu per la dreta → 2**(3**2)
console.log(!true && false);   // false: ! s'aplica abans que &&

Un cas realista a Nómada Tasques:

const horesIvan = 12;
const horesLucia = 8;
const horesMarta = 6;

// Mitjana de l'equip: què creus que dona?
console.log(horesIvan + horesLucia + horesMarta / 3);   // 22 ← malament!
console.log((horesIvan + horesLucia + horesMarta) / 3); // 8.67 ← correcte

En el primer cas, / s'aplica abans que +, així que només es divideixen les hores de la Marta.

Consell definitiu: no memoritzis la taula. Fes servir parèntesis. Costen dos caràcters i eliminen qualsevol dubte, tant per al motor com per a qui llegeixi el teu codi. Ningú no ha criticat mai un parèntesi de més; molts errors vénen d'un de menys.

  1. Aplicació: la càrrega d'hores de l'equip

Ajuntem-ho tot en un cas real de Taller Nómada. La Marta vol saber com està repartida la càrrega de treball abans d'assignar tasques noves.

'use strict';

// --- Dades de partida ---------------------------------------------
const MAX_HORES_SETMANA = 40;

const responsable = 'Iván';
const horesTasca1 = 12;   // Redissenyar la sala polivalent
const horesTasca2 = 8;    // Cartelleria del taller de serigrafia
const horesTasca3 = 4.5;  // Revisar el catàleg de tardor

// Aquesta dada podria no arribar (per exemple, si la tasca encara no s'ha estimat)
const horesTasca4 = null;

// --- Càlculs -------------------------------------------------------

// 1. Hores assignades. Amb ?? tractem l'estimació que falta com a 0
const horesAssignades =
  horesTasca1 + horesTasca2 + horesTasca3 + (horesTasca4 ?? 0);

// 2. Hores lliures (podria sortir negatiu si està sobrecarregat)
const horesLliures = MAX_HORES_SETMANA - horesAssignades;

// 3. Percentatge d'ocupació, arrodonit
const percentatgeOcupacio = Math.round((horesAssignades / MAX_HORES_SETMANA) * 100);

// 4. Estat de la càrrega amb un ternari encadenat
const estatCarrega =
  percentatgeOcupacio >= 100 ? 'sobrecarregat' :
  percentatgeOcupacio >= 75  ? 'alt' :
  percentatgeOcupacio >= 40  ? 'equilibrat' :
                               'amb marge';

// 5. Pot acceptar una tasca nova de 8 hores?
const HORES_TASCA_NOVA = 8;
const potAcceptarla = horesLliures >= HORES_TASCA_NOVA;

// --- Sortida -------------------------------------------------------
console.log(`=== Càrrega setmanal de ${responsable} ===`);
console.log(`Assignades: ${horesAssignades} h de ${MAX_HORES_SETMANA} h`);
console.log(`Lliures:    ${horesLliures} h`);
console.log(`Ocupació:   ${percentatgeOcupacio}% (${estatCarrega})`);
console.log(
  `Pot assumir ${HORES_TASCA_NOVA} h més? ${potAcceptarla ? 'Sí' : 'No'}`
);

// 6. Avís només si està en zona de risc, fent servir el curtcircuit
percentatgeOcupacio >= 75 &&
  console.warn(`Atenció: ${responsable} està al ${percentatgeOcupacio}%`);

Sortida:

=== Càrrega setmanal de Iván ===
Assignades: 24.5 h de 40 h
Lliures:    15.5 h
Ocupació:   61% (equilibrat)
Pot assumir 8 h més? Sí

Repassem les decisions que s'han pres:

  1. horesTasca4 ?? 0 tracta l'estimació absent com a zero hores. Amb || hauria funcionat igual aquí, però si l'estimació fos legítimament 0, || l'hauria substituïda per 0 igualment i en altres contextos donaria problemes. ?? expressa exactament la intenció: "si no hi ha dada, fes servir 0".
  2. Els parèntesis a (horesAssignades / MAX_HORES_SETMANA) * 100 no són estrictament necessaris (/ i * tenen la mateixa precedència i s'avaluen d'esquerra a dreta), però deixen claríssima la intenció.
  3. Math.round evita mostrar 61.25%.
  4. El ternari encadenat classifica la càrrega en quatre trams. Està alineat perquè es llegeixi com una taula.
  5. potAcceptarla és un booleà amb nom d'afirmació; a la sortida es converteix a text amb un altre ternari.
  6. El curtcircuit && executa l'avís només si se supera el llindar. Aquí no s'executa, perquè 61 >= 75 és fals.

Errors Habituals i Consells

Errors habituals

  • Sumar text sense voler. '12' + 8 dona '128'. Les dades de formularis arriben sempre com a text; converteix-les abans d'operar.
  • Oblidar els parèntesis en una mitjana. a + b + c / 3 no és la mitjana. És l'error de càlcul més repetit del món.
  • Fer servir || per a valors per defecte numèrics. hores || 8 converteix un 0 legítim en 8. Fes servir ??.
  • Dividir sense comprovar el divisor. x / 0 dona Infinity silenciosament i contamina tots els càlculs posteriors.
  • Barrejar ?? amb || o && sense parèntesis. És un SyntaxError.
  • Abusar de x++ dins d'expressions. i++ + ++i és un endevinalla, no codi.
  • Posar ?. a tot arreu. Silencia errors reals. Fes-lo servir només on el valor pugui faltar legítimament.
  • Confondre = amb == o ===. if (estat = 'feta') assigna en lloc de comparar, i sempre resulta cert.

Consells

  • Fes servir parèntesis sempre que hi hagi més d'un operador. La claredat val més que la brevetat.
  • ?? per a valors per defecte, || només quan vulguis descartar també 0 i ''.
  • Template literals per a tot text compost. Elimina d'una tacada els errors de concatenació.
  • El ternari, per triar un valor. Si necessites executar diverses instruccions, fes servir if.
  • Anomena els resultats intermedis. const percentatgeOcupacio = ... és infinitament més llegible que ficar el càlcul sencer dins d'un console.log.
  • Arrodoneix en mostrar, no en calcular. Si arrodoneixes enmig d'una cadena de càlculs, acumules error.

Exercicis

Exercici 1: Prediu el resultat

Escriu què imprimeix cada línia i per què:

console.log(2 + 3 * 4);               // A
console.log('8' + 4);                 // B
console.log('8' - 4);                 // C
console.log(10 % 3);                  // D
console.log(2 ** 3 ** 2);             // E

let i = 5;
console.log(i++);                     // F
console.log(i);                       // G

console.log(0 || 40);                 // H
console.log(0 ?? 40);                 // I
console.log('' ?? 'Sense assignar');  // J
console.log(null ?? 'Sense assignar');// K
console.log(!!'feta');                // L

Exercici 2: Repartiment rotatiu de tasques

L'equip de Taller Nómada té tres persones en aquest ordre: posició 0 = Marta, 1 = Iván, 2 = Lucía. Les tasques s'assignen per torns segons el seu número.

Escriu un script que, donat un numeroTasca, calculi i imprimeixi:

  1. La posició de l'equip a la qual correspon (fes servir %).
  2. Si el número de tasca és parell o senar.
  3. Un missatge amb template literal de l'estil: La tasca 7 correspon a la posició 1 (número senar).

Prova'l amb els números 5, 6 i 7.

Exercici 3: Informe de càrrega de la Lucía

Escriu un script que calculi la càrrega setmanal de la Lucía amb aquestes dades:

  • Màxim setmanal: 40 hores.
  • Tasques assignades: 10, 6.5 i 3 hores.
  • Una quarta tasca l'estimació de la qual encara no existeix (val null).
  • Ja ha dedicat 12 hores de les assignades.

Calcula i mostra:

  1. Total d'hores assignades (l'estimació absent compta com a 0, fent servir ??).
  2. Hores pendents de dedicar.
  3. Percentatge d'avenç sobre el que està assignat, arrodonit a enter.
  4. Percentatge d'ocupació sobre el màxim setmanal, arrodonit.
  5. Si pot assumir una tasca nova de 20 hores (booleà mostrat com a "Sí"/"No" amb un ternari).
  6. Un avís amb console.warn, fent servir el curtcircuit &&, només si l'ocupació supera el 40%.

Solucions

Exercici 1

Línia Resultat Explicació
A 14 * té més precedència que +: 2 + (3*4)
B '84' Un dels operands és text: + concatena
C 4 - no concatena: converteix '8' a nombre
D 1 El residu de dividir 10 entre 3
E 512 ** associa per la dreta: 2 ** (3**2) = 2**9
F 5 Forma sufixa: retorna el valor antic
G 6 Però la variable ja està incrementada
H 40 0 és falsy, així que || passa al segon operand
I 0 ?? només actua davant de null o undefined
J '' La cadena buida no és null ni undefined
K 'Sense assignar' null sí que activa ??
L true !! converteix a booleà; un text no buit és truthy

Exercici 2

'use strict';

const numeroTasca = 7;

// 1. Posició a l'equip (3 persones: 0, 1, 2)
const MIDA_EQUIP = 3;
const posicio = numeroTasca % MIDA_EQUIP;

// 2. Parell o senar
const esParell = numeroTasca % 2 === 0;
const paritat = esParell ? 'parell' : 'senar';

// 3. Missatge
console.log(
  `La tasca ${numeroTasca} correspon a la posició ${posicio} (número ${paritat}).`
);

Resultats:

numeroTasca % 3 Posició Paritat
5 5 % 3 2 (Lucía) senar
6 6 % 3 0 (Marta) parell
7 7 % 3 1 (Iván) senar

Exercici 3

'use strict';

// --- Dades ---------------------------------------------------------
const MAX_HORES_SETMANA = 40;
const responsable = 'Lucía';

const horesTasca1 = 10;
const horesTasca2 = 6.5;
const horesTasca3 = 3;
const horesTasca4 = null;   // encara sense estimar

const horesDedicades = 12;

// --- Càlculs -------------------------------------------------------
const horesAssignades =
  horesTasca1 + horesTasca2 + horesTasca3 + (horesTasca4 ?? 0);

const horesPendents = horesAssignades - horesDedicades;

const percentatgeAvenc = Math.round((horesDedicades / horesAssignades) * 100);
const percentatgeOcupacio = Math.round((horesAssignades / MAX_HORES_SETMANA) * 100);

const HORES_TASCA_NOVA = 20;
const horesLliures = MAX_HORES_SETMANA - horesAssignades;
const potAcceptarla = horesLliures >= HORES_TASCA_NOVA;

// --- Sortida -------------------------------------------------------
console.log(`=== Càrrega setmanal de ${responsable} ===`);
console.log(`Assignades: ${horesAssignades} h`);
console.log(`Dedicades:  ${horesDedicades} h`);
console.log(`Pendents:   ${horesPendents} h`);
console.log(`Avenç:      ${percentatgeAvenc}%`);
console.log(`Ocupació:   ${percentatgeOcupacio}% de ${MAX_HORES_SETMANA} h`);
console.log(
  `Pot assumir ${HORES_TASCA_NOVA} h més? ${potAcceptarla ? 'Sí' : 'No'}`
);

percentatgeOcupacio > 40 &&
  console.warn(`Atenció: ${responsable} supera el 40% d'ocupació.`);

Sortida:

=== Càrrega setmanal de Lucía ===
Assignades: 19.5 h
Dedicades:  12 h
Pendents:   7.5 h
Avenç:      62%
Ocupació:   49% de 40 h
Pot assumir 20 h més? Sí
⚠ Atenció: Lucía supera el 40% d'ocupació.

Punts a destacar:

  • horesTasca4 ?? 0 neutralitza la dada absent. Sense aquest operador, null acabaria convertint-se a 0 de totes maneres per coerció implícita, però escriure-ho de manera explícita documenta la intenció i no depèn d'una conversió automàtica que potser no controles.
  • Els parèntesis als percentatges garanteixen que primer es divideix i després es multiplica per 100.
  • El càlcul de potAcceptarla: horesLliures val 40 - 19.5 = 20.5, i 20.5 >= 20 és true, així que el resultat és "Sí" per un marge molt just de mitja hora. Si haguessis estimat la quarta tasca en només una hora, la resposta hauria canviat. Aquest és exactament el tipus de càlcul al límit que convé que faci el programa i no una persona amb una calculadora.

Conclusió

Ja saps operar amb dades. Manegues els aritmètics (+ - * / % **), inclòs el mòdul per a repartiments cíclics, i coneixes la doble personalitat del +. Distingeixes les formes prefixa i sufixa de ++ i --. Fas servir els operadors d'assignació compostos (+=, -=, *=...). Entens els lògics &&, || i !, la seva avaluació de curtcircuit i el fet que retornen un operand, no un booleà. Saps quan fer servir ?? en lloc de || per a valors per defecte, i aplicar ??= i ?. per treballar amb dades que poden faltar. Fas servir el ternari per triar valors dins d'expressions, prefereixes els template literals a la concatenació, i sobretot has après la lliçó més rendible de totes: quan dubtis de la precedència, posa parèntesis.

Amb tot això has construït el primer càlcul útil de Nómada Tasques: l'informe de càrrega setmanal d'un membre de l'equip de Taller Nómada.

Però has vist aparèixer un fantasma diverses vegades: '8' + 4 dona '84', null es converteix en 0 en sumar, 0 és falsy i '' també. Aquest és el terreny on més s'ensopega. A la lliçó següent, Conversió de Tipus i Comparacions, el desbrossaràs completament: coerció implícita i explícita, la llista exacta de valors falsy i la diferència entre == i ===. És la lliçó que evita la majoria dels errors d'un principiant.

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