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
- Operadors aritmètics
- Increment i decrement: prefix i sufix
- Operadors d'assignació
- Operadors lògics i curtcircuit
- Coalescència nul·la:
??i??= - Encadenament opcional:
?. - L'operador ternari
? : - Concatenació enfront de template literals
- Precedència d'operadors
- Aplicació: la càrrega d'hores de l'equip
- Errors Habituals i Consells
- Exercicis
- Conclusió
- 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); // 41.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); // falseRepartir 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ánEl 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:
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à malamentLa 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 convertirA Conversió de Tipus i Comparacions veuràs exactament per què passa això i com protegir-te'n.
- 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); // 5Tots 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); // 6Mnemotè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:
- 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íaRecorda que les variables assignades amb aquests operadors s'han de declarar amb let: amb const obtindries un TypeError.
- 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); // false4.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":
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 || bretornaasiaés truthy; si no, retornab.a && bretornaasiaés falsy; si no, retornab.
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 0Com 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:
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.
- Coalescència nul·la:
?? i ??=
?? 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 respectaComparativa 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 — correcte5.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 tocaEquival 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ó
- 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 nullAquest TypeError atura el programa sencer. Amb ?.:
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); // undefinedSense ?., 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ò.
- L'operador ternari
? :
? :És l'únic operador de JavaScript que pren tres operands. La seva forma:
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 curtaEs 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 |
- 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üitatFes servir template literals sempre que combinis text i variables. No hi ha cap motiu per no fer-ho.
- 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) * 4 → 20 |
| 2 | ?. accés opcional |
Esquerra | tasca?.titol |
| 3 | ++ -- sufixos |
— | i++ |
| 4 | ! ++ -- prefixos, typeof |
Dreta | !estaFeta |
| 5 | ** |
Dreta | 2 ** 3 ** 2 → 512 |
| 6 | * / % |
Esquerra | 2 + 3 * 4 → 14 |
| 7 | + - |
Esquerra | 10 - 3 - 2 → 5 |
| 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 ← correcteEn 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.
- 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:
horesTasca4 ?? 0tracta l'estimació absent com a zero hores. Amb||hauria funcionat igual aquí, però si l'estimació fos legítimament0,||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".- Els parèntesis a
(horesAssignades / MAX_HORES_SETMANA) * 100no són estrictament necessaris (/i*tenen la mateixa precedència i s'avaluen d'esquerra a dreta), però deixen claríssima la intenció. Math.roundevita mostrar61.25%.- El ternari encadenat classifica la càrrega en quatre trams. Està alineat perquè es llegeixi com una taula.
potAcceptarlaés un booleà amb nom d'afirmació; a la sortida es converteix a text amb un altre ternari.- 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' + 8dona'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 / 3no é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 || 8converteix un0legítim en8. Fes servir??. - Dividir sense comprovar el divisor.
x / 0donaInfinitysilenciosament i contamina tots els càlculs posteriors. - Barrejar
??amb||o&&sense parèntesis. És unSyntaxError. - 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é0i''.- 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'unconsole.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'); // LExercici 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:
- La posició de l'equip a la qual correspon (fes servir
%). - Si el número de tasca és parell o senar.
- 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:
- Total d'hores assignades (l'estimació absent compta com a 0, fent servir
??). - Hores pendents de dedicar.
- Percentatge d'avenç sobre el que està assignat, arrodonit a enter.
- Percentatge d'ocupació sobre el màxim setmanal, arrodonit.
- Si pot assumir una tasca nova de 20 hores (booleà mostrat com a "Sí"/"No" amb un ternari).
- 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 ?? 0neutralitza la dada absent. Sense aquest operador,nullacabaria convertint-se a0de 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:horesLliuresval40 - 19.5 = 20.5, i20.5 >= 20éstrue, 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
- Què és JavaScript?
- Configuració del teu Entorn de Desenvolupament
- El teu Primer Programa en JavaScript
- Sintaxi i Conceptes Bàsics de JavaScript
- Variables i Tipus de Dades
- Operadors Bàsics
- Conversió de Tipus i Comparacions
- El Projecte del Curs: Nómada Tasques
Mòdul 2: Estructures de Control
- Sentències Condicionals
- Bucles: for, while, do-while
- Sentències Switch
- Control del Flux: break, continue i Bucles Imbricats
- Gestió d'Errors amb try-catch
Mòdul 3: Funcions
- Definició i Crida de Funcions
- Expressions de Funció i Funcions Fletxa
- Paràmetres i Valors de Retorn
- Àmbit i Closures
- Hoisting i el Context d'Execució
- Funcions d'Ordre Superior
- Recursivitat
Mòdul 4: Objectes i Arrays
- Introducció als Objectes
- Mètodes d'Objecte i la Paraula Clau
this - Arrays: Conceptes Bàsics i Mètodes
- Iteració sobre Arrays
- Cercar, Ordenar i Agregar Dades: find, sort i reduce
- Desestructuració d'Arrays
- Desestructuració d'Objectes, Spread i Rest
- JSON i Còpies d'Objectes
Mòdul 5: Objectes i Funcions Avançades
- Prototips i Herència
- Classes i Programació Orientada a Objectes
- Encapsulació: Getters, Setters i Camps Privats
- Mòduls i Importació/Exportació
- JavaScript Asíncron: Callbacks
- Promeses i Async/Await
- El Bucle d'Esdeveniments i la Cua de Microtasques
- Iteradors i Generadors
Mòdul 6: El Model d'Objectes del Document (DOM)
- Introducció al DOM
- Selecció i Manipulació d'Elements del DOM
- Gestió d'Esdeveniments
- Propagació, Delegació i Esdeveniments Personalitzats
- Creació i Eliminació d'Elements del DOM
- Renderitzat de Llistes i Plantilles HTML
- Gestió i Validació de Formularis
Mòdul 7: APIs del Navegador i Temes Avançats
- Emmagatzematge Local i de Sessió
- Fetch API i AJAX
- Peticions Robustes: Errors, Timeouts i AbortController
- WebSockets
- Service Workers i Aplicacions Web Progressives (PWAs)
- APIs del Navegador Essencials
- Introducció a WebAssembly
Mòdul 8: Proves i Depuració
- Depuració de JavaScript
- Qualitat de Codi: ESLint, Prettier i Convencions
- Proves Unitàries amb Jest
- Dobles de Prova: Mocks, Stubs i Spies
- Proves d'Integració
- Proves d'Extrem a Extrem amb Cypress
Mòdul 9: Rendiment i Optimització
- Mesurar Abans d'Optimitzar: DevTools i Web Vitals
- Optimització del Rendiment de JavaScript
- Gestió de Memòria
- Manipulació Eficient del DOM
- Càrrega Diferida i Divisió de Codi
Mòdul 10: Frameworks i Llibreries de JavaScript
- Per Què Existeixen els Frameworks
- Introducció a React
- Gestió d'Estat amb Redux
- Conceptes Bàsics de Vue.js
- Conceptes Bàsics d'Angular
- Triar el Framework Adequat
