# 1. Introducció al Javascript

# ECMAScript (ES)

**ECMAScript (sovint abreujat com ES)** és l'**especificació (o estàndard)** tècnica que defineix com ha de funcionar el llenguatge de programació **JavaScript**.

### Què és ECMAScript?

ECMAScript és un **estàndard formal** de llenguatge de programació desenvolupat i publicat per **ECMA International** (concretament, el comitè tècnic TC39) sota la denominació **ECMA-262**.

- **Estàndard, no llenguatge:** ECMAScript no és un llenguatge per si mateix; és la **normativa** que defineix la sintaxi, la semàntica, les llibreries estàndard, i les API de *com* ha de ser un llenguatge de *scripting* d'ús general.
- **JavaScript és una implementació:** **JavaScript** és la implementació més coneguda i predominant d'aquest estàndard. Altres implementacions inclouen JScript (de Microsoft) o ActionScript (d'Adobe), tot i que estan gairebé obsoletes.
- **Versions:** Les versions es publiquen anualment. La versió més famosa és **ECMAScript 2015 (ES6)**, que va introduir canvis fonamentals com `let`, `const`, classes i funcions de fletxa. Les versions posteriors s'anomenen per l'any (ES2016, ES2017, etc.).

#### Importància d'ECMAScript

La importància d'ECMAScript rau principalment en la **estandardització, la compatibilitat i l'evolució** del llenguatge web més crucial del món: JavaScript.

##### 1. Garantia de Compatibilitat (Estandardització)

L'estàndard assegura que **JavaScript funcioni de la mateixa manera** independentment d'on s'executi:

- En navegadors diferents (Chrome, Firefox, Safari, Edge).
- En entorns de servidor (Node.js).
- En aplicacions mòbils híbrides.

Sense un estàndard, cada navegador implementaria JavaScript a la seva manera, trencant la interoperabilitat i fent impossible el desenvolupament web universal.

##### 2. Evolució i Modernització del Llenguatge

El procés d'ECMAScript és el motor que permet a JavaScript **evolucionar i adoptar noves funcionalitats** (com el mòduls ES, *async/await* o l'operador *spread*).

- Mantenir-se al dia amb ECMAScript permet als desenvolupadors utilitzar **sintaxi més neta, eficient i robusta**, fent que el codi sigui més fàcil de llegir i mantenir.

##### 3. Foment de la Innovació

En proporcionar un procés clar per proposar i aprovar noves característiques (el procés de "stages"), ECMAScript:

- Impulsa la **innovació** a la plataforma web.
- Permet als creadors de navegadors i a la comunitat de desenvolupament consensuar i provar noves funcionalitats abans que esdevinguin un estàndard.

### Característiques Principals d'ECMAScript 2024 (ES15)

Els canvis principals de l'ES2024 són els següents:

#### 1. Agrupació d'Iterables (`.groupBy()`)

S'afegeixen mètodes per agrupar elements d'arrays i altres iterables segons una clau retornada per una funció de *callback*.

- **`Object.groupBy(iterable, callback)`**: Agrupa els elements en un **objecte** on les claus són els resultats de la *callback*.
- **`Map.groupBy(iterable, callback)`**: Agrupa els elements en un **Map**, la qual cosa és útil si les claus no són de tipus `String` (per exemple, si són objectes o Símbols).

**Cas d'Ús:** Simplifica la classificació d'una llista d'objectes sense haver de fer un `reduce` manualment.

```javascript
const productes = [
  { nom: 'Poma', color: 'vermell' },
  { nom: 'Plàtan', color: 'groc' },
  { nom: 'Cirera', color: 'vermell' }
];

const productesPerColor = Object.groupBy(productes, item => item.color);
/*
{
  vermell: [ { nom: 'Poma', color: 'vermell' }, { nom: 'Cirera', color: 'vermell' } ],
  groc: [ { nom: 'Plàtan', color: 'groc' } ]
}
*/
```

#### 2. Creació Simplificada de Promises (`Promise.withResolvers()`)

Aquest mètode estàtic proporciona una manera més neta de crear una **Promise** i obtenir directament les seves funcions de resolució (`resolve`) i rebuig (`reject`) sense la necessitat d'encapsular-les.

**Abans (més verbós):**

```javascript
let resolve, reject;
const promesa = new Promise((res, rej) => {
  resolve = res;
  reject = rej;
});
// ...
```

**Ara (més directe):**

```javascript
const { promise, resolve, reject } = Promise.withResolvers();

// ... es pot cridar resolve() o reject() des de qualsevol lloc
```

#### 3. Novetats en Expressions Regulars: Flag `/v`

S'introdueix el nou *flag* **`/v` (Unicode Sets Mode)** per a les expressions regulars, millorant significativament la gestió de caràcters Unicode:

- **Operacions amb conjunts (`--`, `&&`, `\q{...}`):** Permet realitzar operacions de conjunt (unió, intersecció, diferència) dins de les classes de caràcters. *Exemple:* Utilitzar `[A-Z--[AEIOU]]` per trobar només consonants majúscules.
- **Propietats de cadena Unicode:** Millora la forma de coincidir amb *sequences* d'Unicode complexes, com emojis.

#### 4. Mètodes per a Strings "Ben Formades" (`.isWellFormed()`, `.toWellFormed()`)

Aquests mètodes ajuden a tractar problemes amb la codificació **UTF-16** a JavaScript (concretament, amb els "lone surrogates" que poden causar errors).

- **`string.isWellFormed()`**: Retorna `true` si la cadena no conté seqüències de codificació invàlides (és a dir, si està "ben formada").
- **`string.toWellFormed()`**: Retorna una nova cadena on totes les seqüències mal formades són reemplaçades pel **Caràcter de Reemplaçament Unicode** (`U+FFFD`), assegurant la robustesa.

#### 5. Resizing i Transferència d'ArrayBuffers

Es millora la manipulació de `ArrayBuffer` (utilitzats per dades binàries en contexts d'alt rendiment com WebAssembly o Web Workers).

- **`ArrayBuffer.prototype.resize()`**: Permet canviar la mida d'un `ArrayBuffer` al seu lloc.
- **`ArrayBuffer.prototype.transfer()`**: Permet transferir eficientment la propietat de la memòria d'un `ArrayBuffer` a un altre context (per exemple, a un *Web Worker*) evitant una costosa operació de còpia.

### Estatus ES2025 i Més Enllà

El procés d'ECMAScript és continu. Les funcionalitats que s'han finalitzat (Etapa 4) i que seran part d'**ECMAScript 2025 (ES2025)** inclouen:

- **Import Attributes (`import ... with { type: 'json' }`):** Permet importar mòduls que no són JavaScript (com arxius JSON) de forma nadiua.
- **Iterator Helpers:** Afegeix mètodes útils (`map`, `filter`, `take`, `drop`) a tots els iteradors, no només als Arrays, permetent un codi més expressiu i càrregues *lazy* de dades.
- **Set Methods:** Afegeix operacions matemàtiques de conjunts com `union()`, `intersection()`, i `difference()` a l'objecte `Set`.

<div class="code-block ng-tns-c3729132635-45 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1"><div class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-45 ng-star-inserted">  
</div></div>

# Fonaments de JS

# Javascript dins HTML, on?

Afegir codi JavaScript a una pàgina HTML és un pas fonamental per fer que el lloc web sigui dinàmic i interactiu. Hi ha tres maneres principals de fer-ho,

## 1. JavaScript Intern (Inline)

Aquesta forma implica escriure el codi JavaScript **directament dins de les etiquetes HTML** o dins de l'etiqueta `<script>` al mateix fitxer HTML.

### A. Dins de l'etiqueta `<script>`

El codi s'ubica al bloc `<script>` dins del `<head>` o, preferiblement, just abans de tancar l'etiqueta `</body>`.

```html

<html>
<head>
    <title>Intern</title>
</head>
<body>
    <h1>Exemple Intern</h1>
    <script>
        console.log("Aquest és codi JavaScript intern.");
    </script>
</body>
</html>
```

### B. Com a atribut d'un element HTML (Gestors d'esdeveniments)

El codi s'associa a un esdeveniment específic d'un element (p. ex., un clic).

```html
<button onclick="alert('Hola món!');">Clicar</button>
```

Afegir codi JavaScript a una pàgina HTML és un pas fonamental per fer que el lloc web sigui dinàmic i interactiu. Hi ha tres maneres principals de fer-ho, cadascuna amb els seus propis avantatges i inconvenients.





### Avantatges i Inconvenients (Intern)

<div class="horizontal-scroll-wrapper" id="bkmrk-avantatges-inconveni"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Ràpid i senzill** per a scripts molt curts.</td><td>**Barreja de responsabilitats** (HTML i JS).</td></tr><tr><td>**No requereix fitxers externs** (útil per a prototips o proves).</td><td>**Difícil de mantenir** i actualitzar en pàgines grans.</td></tr><tr><td>Es pot posar directament en l'element (opció 1B).</td><td>**No es pot emmagatzemar en memòria cau (cache)**, la qual cosa afecta el rendiment.</td></tr></tbody></table>

</div></div></div></div>### Casos d'Ús (Intern)

- **Scripts molt petits i únics:** Per a funcions de depuració, missatges d'alerta o codi que és exclusiu d'una sola pàgina i que no es reutilitzarà.
- **Gestors d'esdeveniments simples:** Quan s'activa una funció molt breu directament des d'un element, encara que es prefereix assignar esdeveniments amb JS extern per mantenir el codi net.

Afegir codi JavaScript a una pàgina HTML és un pas fonamental per fer que el lloc web sigui dinàmic i interactiu. Hi ha tres maneres principals de fer-ho, cadascuna amb els seus propis avantatges i inconvenients.

Afegir codi JavaScript a una pàgina HTML és un pas fonamental per fer que el lloc web sigui dinàmic i interactiu. Hi ha tres maneres principals de fer-ho, cadascuna amb els seus propis avantatges i inconvenients.

## 2. JavaScript Extern (External)

Aquesta és la **forma més recomanada** per a la majoria d'aplicacions web. El codi JavaScript es guarda en un fitxer separat amb l'extensió `.js` i es vincula al document HTML mitjançant l'etiqueta `<script>` amb l'atribut `src`.

### Implementació

Fitxer HTML:

```html

<html>
<head>
    <title>Extern</title>
</head>
<body>
    <h1>Exemple Extern</h1>
    <script src="scripts/el-meu-codi.js"></script>
</body>
</html>
```

Fitxer `scripts/el-meu-codi.js`:

```javascript
// Aquest és el contingut del fitxer .js
function saluda() {
    console.log("Hola des del fitxer extern!");
}
saluda();
```

### Avantatges i Inconvenients (Extern)

<div class="horizontal-scroll-wrapper" id="bkmrk-avantatges-inconveni-1"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Separació de preocupacions:** Codi més net, mantenible i reutilitzable.</td><td>Requereix una **sol·licitud HTTP addicional** (una per carregar el fitxer `.js`).</td></tr><tr><td>**Rendiment:** El fitxer es pot emmagatzemar en **memòria cau (cache)** pel navegador, fent que les pàgines subsegüents es carreguin més ràpidament.</td><td>Si el fitxer no es carrega correctament, el codi JS no s'executarà.</td></tr><tr><td>**Facilita el treball en equip** i l'organització en projectes grans.</td><td> </td></tr></tbody></table>

</div></div></div></div>### Casos d'Ús (Extern)

- **El cas d'ús per defecte:** Aquesta és la millor pràctica per a qualsevol projecte que no sigui trivial.
- **Lògica reutilitzable:** Per a llibreries, components d'interfície d'usuari (UI) o qualsevol funció que s'utilitzi en múltiples pàgines.

## 3. Com a Mòdul JavaScript (Module)

Des de ES6, JavaScript té un sistema de mòduls propi. Aquesta és una forma més moderna i estructurada d'usar codi extern.

### Implementació

Es fa servir l'atribut **`type="module"`** a l'etiqueta `<script>`.

```html
<body>
    <h1>Exemple Mòdul</h1>
    <script type="module" src="app.js"></script>
</body>
```

### Avantatges i Inconvenients (Mòdul)

<div class="horizontal-scroll-wrapper" id="bkmrk-avantatges-inconveni-2"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Àmbit (Scope) de mòdul:** Les variables i funcions declarades no es "fugen" a l'àmbit global, evitant conflictes.</td><td>**Requereix un servidor web** per funcionar (no funciona només obrint el fitxer HTML localment a causa de restriccions de CORS).</td></tr><tr><td>Permet usar les sentències **`import` i `export`** per organitzar el codi.</td><td>Compatibilitat limitada amb **navegadors molt antics** (encara que avui dia és molt alta).</td></tr><tr><td>S'executa automàticament com a **`defer`** (vegeu la secció següent).</td><td> </td></tr></tbody></table>

</div></div></div></div>### Casos d'Ús (Mòdul)

- **Desenvolupament modern:** Essencial per a projectes grans i estructurats basats en *frameworks* o llibreries (React, Vue, Angular) que utilitzen la importació/exportació de components.
- **Evitar contaminació global:** Quan es vol assegurar que el codi estigui ben encapsulat.

### Exemple (mòdul)

**El Mòdul de Funcionalitats (utils.js).** Aquest fitxer conté funcions o variables que volem reutilitzar en altres parts del nostre codi.

```javascript
// utils.js

// 1. Exportació amb nom (Named Export)
export const PI = 3.14159;

export function suma(a, b) {
    return a + b;
}

// 2. Exportació per defecte (Default Export)
// La funció principal del mòdul o la més rellevant.
export default function multiplica(a, b) {
    return a * b;
}
```

**El Mòdul Principal (app.js).** Aquest fitxer importa els valors i les funcions del fitxer utils.js per utilitzar-los.

```javascript
// app.js

// 1. Importació amb nom: S'importa utilitzant els noms exactes.
import { PI, suma } from './utils.js';

// 2. Importació per defecte: Es pot assignar el nom que vulguis (aquí 'mult').
import mult from './utils.js';


console.log("--- Execució del Mòdul ---");

// Ús de la variable exportada
const areaCercle = PI * 5 * 5;
console.log(`L'àrea d'un cercle amb r=5 és: ${areaCercle.toFixed(2)}`);
// Sortida: L'àrea d'un cercle amb r=5 és: 78.54

// Ús de la funció suma
console.log(`La suma de 10 i 5 és: ${suma(10, 5)}`);
// Sortida: La suma de 10 i 5 és: 15

// Ús de la funció per defecte (multiplica)
console.log(`La multiplicació de 10 i 5 és: ${mult(10, 5)}`);
// Sortida: La multiplicació de 10 i 5 és: 50
```

**El Fitxer HTML (index.html).** La clau aquí és l'atribut type="module" a l'etiqueta &lt;script&gt;. Això indica al navegador que carregui i executi app.js segons les regles dels mòduls d'ECMAScript, habilitant l'ús d'import.

```html

<html>
<head>
    <title>Exemple Mòduls JS</title>
</head>
<body>
    <h1>Obre la Consola del Navegador (F12) per veure els resultats</h1>

    <script type="module" src="app.js"></script>
</body>
</html>
```

<p class="callout info">Una característica important dels mòduls és que, en lloc de contaminar l'àmbit global, les variables i funcions de utils.js (com PI i suma) són privades per defecte i només són accessibles a app.js mitjançant les declaracions explícites d'import. Si intentessis accedir a PI directament des del &lt;script&gt; de index.html (sense type="module"), rebries un error. Això manté el teu codi organitzat i lliure de conflictes.</p>

</body></html>

# <script> dins html, on?

L'etiqueta `<script>` per incloure codi JavaScript es pot col·locar principalment en **tres llocs** dins d'un document HTML: al **`<head>`**, just abans de tancar el **`</body>`**, o utilitzant els atributs **`async`** o **`defer`** en una ubicació externa (que canvia el seu comportament de càrrega).

A continuació, s'expliquen les opcions, els seus avantatges i els inconvenients:

## 1. Dins de l'etiqueta `<head>`

Col·locar el codi JavaScript dins de la secció `<head>...</head>` de l'HTML.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-opci%C3%B3-codi-comportam"><table style="width: 100%;"><thead><tr><td style="width: 19.6663%;">Opció</td><td style="width: 32.8762%;">Codi</td><td style="width: 47.4576%;">Comportament</td></tr></thead><tbody><tr><td style="width: 19.6663%;">**Estàndard**</td><td style="width: 32.8762%;">`<head><script src="script.js"></script></head>`</td><td style="width: 47.4576%;">El navegador **atura** l'anàlisi del HTML per carregar i executar el script abans de carregar qualsevol contingut del `<body>`.</td></tr><tr><td style="width: 19.6663%;">**Amb `defer`**</td><td style="width: 32.8762%;">`<head><script src="script.js" defer></script></head>`</td><td style="width: 47.4576%;">El navegador **no s'atura**, descarrega el script en paral·lel, i l'executa **just abans** de l'esdeveniment `DOMContentLoaded`.</td></tr><tr><td style="width: 19.6663%;">**Amb `async`**</td><td style="width: 32.8762%;">`<head><script src="script.js" async></script></head>`</td><td style="width: 47.4576%;">El navegador **no s'atura**, descarrega el script en paral·lel, i l'executa **immediatament quan acaba la descàrrega**, interrompent l'anàlisi del DOM si cal.</td></tr></tbody></table>

</div>### Avantatges i Inconvenients (al `<head>`)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-avantatges-inconveni"><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Rendiment amb `defer` o `async`**: Es comença a descarregar el JS abans, però sense bloquejar la renderització del `<body>`.</td><td>**Bloqueig de la pàgina (sense `defer`/`async`):** La pàgina es mostra en blanc fins que el JS ha estat completament carregat i executat.</td></tr><tr><td>**Ideal per a utilitats:** Perfecte per a carregar llibreries que no interactuen amb el DOM.</td><td>**Error d'accés al DOM (sense `defer`/`async`):** Si el script intenta manipular elements del `<body>`, fallarà perquè encara no existeixen.</td></tr><tr><td>**Claritat:** Fa evident que el script és necessari per a la càrrega inicial.</td><td> </td></tr></tbody></table>

</div>## 2. Just abans de tancar el `</body>`

Aquesta és la **ubicació més habitual i tradicionalment recomanada** per als scripts que interactuen amb el DOM.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-opci%C3%B3-codi-comportam-1"><table><thead><tr><td>Opció</td><td>Codi</td><td>Comportament</td></tr></thead><tbody><tr><td>**Estàndard**</td><td>`<body>... Contenido ... <script src="script.js"></script></body>`</td><td>El navegador analitza i renderitza **tot** el HTML del `<body>`. Quan troba l'etiqueta `<script>`, l'executa.</td></tr></tbody></table>

</div>### Avantatges i Inconvenients (al `</body>`)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-avantatges-inconveni-1"><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Rendiment (Percebut):** El contingut HTML es mostra a l'usuari abans que s'executi el JS, millorant la velocitat percebuda.</td><td>**Retard en la interactivitat:** El JS no comença a descarregar-se ni a executar-se fins que el navegador no arriba al final del document.</td></tr><tr><td>**Accés segur al DOM:** Quan s'executa el script, tots els elements HTML ja estan carregats i disponibles.</td><td>**Opció menys neta:** Trenca la separació de preocupacions (la part lògica/recursos al `<head>`) del contingut (`<body>`).</td></tr><tr><td>**No cal `defer`:** Simula el comportament de `defer` de forma nativa per a la interacció amb el DOM.</td><td> </td></tr></tbody></table>

</div>## 3. En mig de `<body>`

**Es pot** posar l'etiqueta `<script>` al mig del `<body>` d'un document HTML. De fet, tradicionalment, era una pràctica comuna, tot i que té implicacions importants per al rendiment i el comportament de la pàgina.

### Comportament i Implicacions

Quan el navegador processa un document HTML, va llegint el codi de dalt a baix. Quan es troba un `<script>` (sense els atributs `async` o `defer`):

1. **S'atura l'anàlisi (Parsing) del HTML:** El navegador atura la construcció de l'arbre DOM (Document Object Model) i la renderització del contingut restant del `<body>`.
2. **Descàrrega i execució:** Descarrega el fitxer JavaScript (si és extern) i l'executa completament.
3. **Represa:** Un cop finalitzada l'execució del script, el navegador reprèn l'anàlisi del HTML que ve a continuació.

### Exemple de Codi

En el següent exemple, el JS s'executarà **després** que s'hagi carregat el `<h1>` però **abans** que el navegador llegeixi i mostri el `<p>`.

```html
<body>
    <h1>Títol de la Pàgina</h1>  <script>
        console.log("El codi JS s'executa ara mateix.");
        // Aquest script bloqueja la càrrega del <p> següent.
    </script>
    
    <p>Aquest paràgraf es retarda fins que el script anterior s'ha executat.</p> 
</body>
```

### Avantatges

- **Accés a elements carregats:** El script pot manipular de manera segura qualsevol element HTML que hagi estat definit *abans* de la seva ubicació. Això elimina la necessitat d'utilitzar escoltadors d'esdeveniments com `DOMContentLoaded` per a aquests elements previs.

### Inconvenients (Per què s'ha d'evitar)

- **Bloqueig de Renderització:** El principal inconvenient és el **bloqueig**. Si el script és gran o requereix temps per descarregar-se, l'usuari veurà la pàgina "congelada" en el punt on es troba el `<script>`, retardant la visualització de la resta del contingut. Això és desastrós per al **rendiment** i l'experiència d'usuari (UX).
- **Accessibilitat Incompleta al DOM:** El script només pot accedir als elements que s'han carregat abans d'ell. Si necessita interactuar amb elements que es troben *després* del seu punt d'inserció, fallarà.

## Millors pràctiques

En JavaScript modern, per evitar bloquejos i garantir el millor rendiment, s'han d'utilitzar els següents mètodes:

1. **Al final del `<body>`:** Aquesta és la solució clàssica per assegurar que tot el DOM es carrega abans que s'executi el JS.
2. **Al `<head>` amb `defer`:** Aquesta és la **millor pràctica moderna**. Permet la descàrrega asíncrona (sense bloquejar el HTML) i garanteix que l'execució del script es realitza un cop el DOM està completament carregat.

<div class="horizontal-scroll-wrapper" id="bkmrk-opci%C3%B3-ubicaci%C3%B3-c%C3%A0rre"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph align-center" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table class=" align-center"><thead><tr><td>Opció</td><td>Ubicació</td><td>Càrrega</td><td>Execució</td></tr></thead><tbody><tr><td>**Recomanada**</td><td>`<head>`</td><td>Paral·lela</td><td>Després del DOM (en ordre)</td></tr><tr><td>**Tradicional**</td><td>Final del `<body>`</td><td>Bloquejant</td><td>Després del DOM (en ordre)</td></tr></tbody></table>

</div><div _ngcontent-ng-c3951549219="" class="table-footer hide-from-message-actions ng-star-inserted" hide-from-message-actions=""></div></div></div></div>En resum, tot i que tècnicament es pot posar un script al mig del `<body>`, no és aconsellable a menys que tinguis una raó molt específica (i normalment d'herència) per fer-ho. **Utilitza `defer` al `<head>` o posa el script just abans de `</body>` per al millor rendiment.**

La decisió depèn de la funcionalitat del script:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-tipus-de-script-ubic"><table><thead><tr><td>Tipus de Script</td><td>Ubicació i Atribut Recomanat</td></tr></thead><tbody><tr><td>**Scripts que manipulen el DOM** (p. ex., un carrusel, un botó interactiu)</td><td>**Abans de `</body>` (sense atributs)**, o **Al `<head>` amb l'atribut `defer`**. (La millor pràctica moderna és `defer`).</td></tr><tr><td>**Scripts d'analítiques o publicitat** (que no depenen del DOM i han de carregar-se ràpidament)</td><td>**Al `<head>` amb l'atribut `async`**.</td></tr><tr><td>**Scripts que es carrega com a mòdul (ES Modules)**</td><td>**Al `<head>` o al `</body>` amb `type="module"`**. Per defecte, aquests mòduls es comporten com si tinguessin l'atribut `defer`.</td></tr></tbody></table>

</div></body>

# Objecte console

L'objecte **`console`** de JavaScript és un objecte global integrat que proporciona accés a la **consola de depuració** del navegador web. El seu propòsit principal és permetre als desenvolupadors **registrar (log)** informació durant l'execució del codi per a propòsits de depuració, monitorització i prova. És el millor amic per saber què està passant "sota el capó" de l'aplicació.

## Mètodes de Registre (Logging) Més Comuns

El mètode més conegut és `console.log()`, però hi ha diversos mètodes essencials per registrar diferents tipus d'informació:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem"><table style="width: 100%;"><thead><tr><td style="width: 21.3349%;">Mètode</td><td style="width: 41.7246%;">Propòsit</td><td style="width: 37.0597%;">Exemple</td></tr></thead><tbody><tr><td style="width: 21.3349%;">**`console.log()`**</td><td style="width: 41.7246%;">Mostra un missatge d'informació general. És el més utilitzat.</td><td style="width: 37.0597%;">`console.log('Valor actual:', x);`</td></tr><tr><td style="width: 21.3349%;">**`console.warn()`**</td><td style="width: 41.7246%;">Emet un missatge d'advertència. Sovint es mostra amb una icona groga ⚠️.</td><td style="width: 37.0597%;">`console.warn('Funció obsoleta.');`</td></tr><tr><td style="width: 21.3349%;">**`console.error()`**</td><td style="width: 41.7246%;">Emet un missatge d'error. Sovint es mostra amb una icona vermella ❌ i inclou una traça de pila (*stack trace*).</td><td style="width: 37.0597%;">`console.error('La connexió ha fallat.');`</td></tr><tr><td style="width: 21.3349%;">**`console.info()`**</td><td style="width: 41.7246%;">Mostra un missatge informatiu similar a `log()`, però es pot filtrar diferentment.</td><td style="width: 37.0597%;">`console.info('Iniciant procés...');`</td></tr><tr><td style="width: 21.3349%;">**`console.dir()`**</td><td style="width: 41.7246%;">Mostra una representació interactiva en format d'arbre de les propietats d'un objecte JavaScript especificat. Útil per a inspeccionar objectes DOM.</td><td style="width: 37.0597%;">`console.dir(document.body);`</td></tr></tbody></table>

</div>## Mètodes Avançats per a l'Organització i Mesura

Aquests mètodes ajuden a estructurar la informació complexa i a mesurar el rendiment.

### 1. Agrupació de Missatges

Permet agrupar missatges per fer la consola més llegible, especialment quan es depuren bucles o funcions que es criden repetidament.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-co"><table><thead><tr><td>Mètode</td><td>Descripció</td></tr></thead><tbody><tr><td>**`console.group(label)`**</td><td>Inicia un nou bloc de missatges amb l'etiqueta `label`.</td></tr><tr><td>**`console.groupCollapsed(label)`**</td><td>Inicia un bloc, però el manté col·lapsat per defecte.</td></tr><tr><td>**`console.groupEnd()`**</td><td>Tanca el bloc d'agrupació actual.</td></tr></tbody></table>

</div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-116 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-116 ng-star-inserted"><span class="ng-tns-c3729132635-116">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-116 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-116"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-116">  
</div></div></div>```javascript
console.group('Detalls de la compra');
console.log('Producte: Llibreta');
console.log('Preu: 15€');
console.groupEnd();
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-116 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-116"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-116"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--1"></div>### 2. Mesura del Temps

Aquests mètodes ajuden a mesurar amb precisió quant de temps triga una part específica del codi a executar-se.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-co-1"><table><thead><tr><td>Mètode</td><td>Descripció</td></tr></thead><tbody><tr><td>**`console.time(label)`**</td><td>Inicia un temporitzador amb una etiqueta única.</td></tr><tr><td>**`console.timeEnd(label)`**</td><td>Atura el temporitzador amb l'etiqueta corresponent i imprimeix el temps transcorregut a la consola.</td></tr></tbody></table>

</div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-117 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-117 ng-star-inserted"><span class="ng-tns-c3729132635-117">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-117 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-117"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-117">  
</div></div></div>```javascript
console.time('Calcul complex');
for (let i = 0; i < 1000000; i++) {
    // Simulació de càlcul
}
console.timeEnd('Calcul complex'); 
// Sortida: Calcul complex: 5.234 ms (exemple)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-117 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-117"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-117"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"></div>### 3. Taules i Assertions

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-co-2"><table style="width: 100%;"><thead><tr><td style="width: 39.3202%;">Mètode</td><td style="width: 60.6798%;">Descripció</td></tr></thead><tbody><tr><td style="width: 39.3202%;">**`console.table(data)`**</td><td style="width: 60.6798%;">Mostra dades (arrays o objectes amb moltes propietats) en un format de taula net i interactiu. 📊</td></tr><tr><td style="width: 39.3202%;">**`console.assert(condition, message)`**</td><td style="width: 60.6798%;">Si la `condition` és falsa, imprimeix l'`message` com un error. Si és certa, no fa res. Útil per a proves ràpides.</td></tr></tbody></table>

</div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-118 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-118 ng-star-inserted"><span class="ng-tns-c3729132635-118">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-118 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-118"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-118">  
</div></div></div>```javascript
const usuaris = [{ nom: 'Anna', edat: 28 }, { nom: 'Pau', edat: 35 }];
console.table(usuaris);

console.assert(2 + 2 === 5, 'Error: 2 + 2 no és 5!'); 
// S'imprimirà l'error només si l'afirmació és falsa
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-118 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_5b064e22e0264530","c_cb55861d8f3a287e",null,"rc_3ce02f205994a993",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-118"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-118"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"></div>

# Objecte window

L'objecte **`window`** és l'objecte més important i fonamental en el desenvolupament de JavaScript al navegador. Representa la **finestra del navegador (o pestanya)** que conté el document DOM.

És, de fet, l'**objecte global** de JavaScript en l'entorn del navegador. Això vol dir que totes les variables, funcions i objectes declarats globalment sense prefix són, en realitat, propietats de l'objecte `window`.

## Rols Clau de l'Objecte `window`

L'objecte `window` té tres rols principals en l'ecosistema del navegador:

### 1. Objecte Global

Totes les variables i funcions declarades globalment en un script formen part de l'objecte `window`.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-131 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a54fa979bf41f6d5","c_cb55861d8f3a287e",null,"rc_f490370ce5a2737a",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-131 ng-star-inserted"><span class="ng-tns-c3729132635-131">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-131 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-131 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-131"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-131"></div></div></div>```javascript
var nomGlobal = "Marc";
function saluda() { console.log("Hola!"); }

// Podem accedir-hi com:
console.log(window.nomGlobal); // Marc
window.saluda(); // Hola!
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-131 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a54fa979bf41f6d5","c_cb55861d8f3a287e",null,"rc_f490370ce5a2737a",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-131"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-131"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>### 2. API del Navegador (Browser API)

L'objecte `window` conté funcions i mètodes per manipular la finestra, gestionar les peticions asíncrones i interaccionar amb el dispositiu de l'usuari.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-%2F-m%C3%A8tode-p"><table><thead><tr><td>Propietat / Mètode</td><td>Propòsit</td><td>Exemple</td></tr></thead><tbody><tr><td>**`alert()`, `prompt()`, `confirm()`**</td><td>Mostra quadres de diàleg (alerts, inputs).</td><td>`window.alert('Avís');`</td></tr><tr><td>**`setTimeout()`, `setInterval()`**</td><td>Gestiona la temporització de l'execució de funcions.</td><td>`window.setTimeout(func, 1000);`</td></tr><tr><td>**`fetch()`**</td><td>Inicia peticions de xarxa.</td><td>`window.fetch('/api/data');`</td></tr><tr><td>**`localStorage` / `sessionStorage`**</td><td>Emmagatzematge de dades persistents al navegador.</td><td>`window.localStorage.setItem(...)`</td></tr></tbody></table>

</div>### 3. Contenidor del DOM i el BOM

L'objecte `window` conté altres objectes importants que formen part del **Model d'Objectes del Navegador (BOM - Browser Object Model)**, i serveix com a porta d'entrada al **Model d'Objectes del Document (DOM)**.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-objecte-%2F-propietat-"><table><thead><tr><td>Objecte / Propietat</td><td>Descripció</td></tr></thead><tbody><tr><td>**`document`**</td><td>L'objecte que representa el **DOM** (el contingut HTML). Sense `window`, no podem manipular el document.</td></tr><tr><td>**`location`**</td><td>Informació sobre l'URL actual i mètodes per carregar noves URL.</td></tr><tr><td>**`history`**</td><td>Permet navegar endavant i endarrere en l'historial del navegador.</td></tr><tr><td>**`navigator`**</td><td>Informació sobre el propi navegador (versió, sistema operatiu, geolocalització).</td></tr><tr><td>**`screen`**</td><td>Informació sobre la pantalla de l'usuari (dimensions, resolució).</td></tr></tbody></table>

</div>## Objecte `window` vs. Objecte `document`

Aquesta és una distinció crucial que sovint confon els principiants:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-window%3A-representa-l">- **`window`**: Representa la **finestra del navegador** (el marc o la pestanya). S'encarrega de l'entorn de l'aplicació, el temps, les URL i l'historial.
- **`document`**: Representa el **contingut HTML** dins d'aquesta finestra (el DOM). S'encarrega dels elements, textos i estils que es mostren.

</div>En poques paraules: **El `document` és una propietat de l'objecte `window`**.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-132 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a54fa979bf41f6d5","c_cb55861d8f3a287e",null,"rc_f490370ce5a2737a",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-132 ng-star-inserted"><span class="ng-tns-c3729132635-132">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-132 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-132 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-132"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-132"></div></div></div>```javascript
// window.document.getElementById('id'); és equivalent a:
document.getElementById('id'); 
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-132 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a54fa979bf41f6d5","c_cb55861d8f3a287e",null,"rc_f490370ce5a2737a",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-132"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-132"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"></div>

# Comentaris

Posar comentaris en JavaScript és essencial per documentar el codi i fer-lo més comprensible per a tu i altres desenvolupadors. Hi ha dues maneres principals de fer-ho: per a línies úniques i per a blocs de text.

## 1. Comentaris d'una sola línia (Single-line comments)

S'utilitzen per comentar una línia de codi o una part d'una línia. El text que segueix el símbol és ignorat pel motor de JavaScript fins al final de la línia.

### Sintaxi

S'utilitzen **dues barres inclinades cap endavant (`//`)**:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-277 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-277 ng-star-inserted"><span class="ng-tns-c3729132635-277">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-277 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-277 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-277"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-277"></div></div></div>```javascript
// Aquesta funció calcula el doble d'un nombre
function doble(x) {
  return x * 2; // Retornem el resultat de la multiplicació
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-277 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-277"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-277"></div></div></div>## 2. Comentaris de multilínia (Multi-line comments)

S'utilitzen per escriure comentaris llargs que ocupen diverses línies, o per comentar temporalment un bloc sencer de codi.

### Sintaxi

Comencen amb **barra inclinada i asterisc (`/*`)** i acaben amb **asterisc i barra inclinada (`*/`)**:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-278 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-278 ng-star-inserted"><span class="ng-tns-c3729132635-278">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-278 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-278 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-278"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-278"></div></div></div>```javascript
/*
Aquest bloc de codi s'encarrega
de la inicialització de l'aplicació.
Inclou la configuració de variables globals
i la càrrega de dades inicials.
*/

function iniciarApp() {
  /*
  // Comentar temporalment un bloc de codi existent
  // let dades = carregarDades();
  // processarDades(dades); 
  */
  console.log("Aplicació iniciada.");
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-278 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-278"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-278"></div></div></div>## 3. JSDoc (Comentaris de Documentació)

Encara que tècnicament són comentaris de múltiples línies, tenen un propòsit especial. **JSDoc** és un sistema d'etiquetes que s'utilitza per documentar funcions, classes i mètodes d'una manera estandarditzada. Moltes eines, com editors de codi (VS Code) o generadors de documentació, poden llegir aquests comentaris per oferir ajuda contextual o crear documentació automàtica.

### Sintaxi

Comencen amb **barra inclinada i doble asterisc (`/**`)**:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-279 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-279 ng-star-inserted"><span class="ng-tns-c3729132635-279">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-279 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-279 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-279"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-279"></div></div></div>```javascript
/**
 * Suma dos nombres i retorna el resultat.
 * @param {number} a - El primer nombre a sumar.
 * @param {number} b - El segon nombre a sumar.
 * @returns {number} La suma total de 'a' i 'b'.
 */
function sumar(a, b) {
  return a + b;
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-279 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_370a00d4c20e54c6","c_cb55861d8f3a287e",null,"rc_bdb7af551286d406",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-279"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-279"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6"></div>

# var vs let

La principal diferència entre `var` i `let` en JavaScript rau en el seu **abast (scope)** i en si permeten la **redeclaració**. **`let` es va introduir a ECMAScript 2015 (ES6)** per a solucionar alguns problemes d'abast de `var`.

### Diferència Principal: Abast (Scope)

<div class="horizontal-scroll-wrapper" id="bkmrk-caracter%C3%ADstica-var-l"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table style="width: 100%;"><thead><tr><td style="width: 18.3424%;">Característica</td><td style="width: 29.3334%;">`var`</td><td style="width: 52.205%;">`let`</td></tr></thead><tbody><tr><td style="width: 18.3424%;">**Abast (Scope)**</td><td style="width: 29.3334%;">**Abast de funció (Function Scope)** o **Abast global (Global Scope)**.</td><td style="width: 52.205%;">**Abast de bloc (Block Scope)**.</td></tr><tr><td style="width: 18.3424%;">**Redeclaració**</td><td style="width: 29.3334%;">**Permesa**. Es pot declarar la mateixa variable diverses vegades en el mateix abast.</td><td style="width: 52.205%;">**No permesa**. Llança un error (`SyntaxError`) si es tenta redeclarar en el mateix abast.</td></tr><tr><td style="width: 18.3424%;">**Hoisting (Elevació)**</td><td style="width: 29.3334%;">La declaració s'eleva (hoists) al cim de la funció/abast global i s'inicialitza amb `undefined`. Es pot usar *abans* de declarar-la (però el valor serà `undefined`).</td><td style="width: 52.205%;">La declaració s'eleva (hoists) al cim del bloc, però no s'inicialitza. No es pot usar *abans* de declarar-la (resulta en un `ReferenceError`). Això es coneix com a **"zona morta temporal" (Temporal Dead Zone)**.</td></tr></tbody></table>

</div></div></div></div>#### Qué és l'Abast?

**Abast de funció (`var`)**: Una variable declarada amb `var` és accessible en qualsevol lloc dins de la funció on ha estat declarada, ignorat els blocs com `if` o `for`.

```javascript
function exempleVar() {
  if (true) {
    var x = 10;
  }
  console.log(x); // Sortida: 10 (Encara accessible fora del bloc `if`)
}
```

**Abast de bloc (`let`)**: Una variable declarada amb `let` només és accessible dins del **bloc** de codi on ha estat declarada (un bloc és qualsevol codi dins de claus `{}`). Això inclou bucles (`for`), condicionals (`if`), i funcions.

```javascript
function exempleLet() {
  if (true) {
    let y = 20;
  }
  // console.log(y); // Error: ReferenceError: y is not defined (No accessible fora del bloc `if`)
}
```

#### Que és el hoisting?

**Hoisting/elevació (var):** La declaració s'eleva al capdamunt del seu àmbit, però la inicialització es manté on es va escriure. Per això, si intentes utilitzar una variable var abans de declarar-la, el seu valor serà undefined.

```javascript
console.log(color); // undefined
var color = "blau";
```

**Hoisting/elevació (let):** La declaració també s'eleva, però no s'inicialitza. Si intentes accedir a una variable let abans de declarar-la, obtindràs un ReferenceError. A l'espai entre l'elevació i la declaració se l'anomena Zona Morta Temporal (Temporal Dead Zone - TDZ).

```javascript
// console.log(forma); // ReferenceError: No es pot accedir a 'forma' abans de la inicialització
let forma = "cercle";
```

### Avantatges i Inconvenients

### `var`

<div class="horizontal-scroll-wrapper" id="bkmrk-avantatges-inconveni"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Compatibilitat històrica** amb versions antigues de JavaScript.</td><td>**Problemes amb l'abast de funció**: Pot causar errors subtils i inesperats, especialment dins de bucles, ja que la variable es "filtra" fora del bloc.</td></tr><tr><td>**Hoisting amb inicialització a `undefined`**: Pot ser convenient en casos molt concrets, tot i que generalment és un inconvenient.</td><td>**Permet la redeclaració**: Això fa que el codi sigui més propens a errors i menys llegible, ja que una variable pot ser redefinida accidentalment.</td></tr></tbody></table>

</div></div></div></div>### `let`

<div class="horizontal-scroll-wrapper" id="bkmrk-avantatges-inconveni-1"><div class="table-block-component"><div _ngcontent-ng-c3951549219="" class="table-block has-export-button"><div _ngcontent-ng-c3951549219="" class="table-content not-end-of-paragraph" jslog="275421;track:impression,attention" not-end-of-paragraph=""><table><thead><tr><td>Avantatges</td><td>Inconvenients</td></tr></thead><tbody><tr><td>**Abast de bloc** (El gran avantatge): Fa que el codi sigui **més previsible i menys propens a errors**, ja que les variables estan confinades on s'espera.</td><td>**No funciona en entorns molt antics** que no admeten ES6 (tot i que avui dia això és rar).</td></tr><tr><td>**Evita la redeclaració**: Ajuda a atrapar errors de tipus alhora d'escriure el codi.</td><td>**Zona morta temporal**: Pot ser un concepte confús per a principiants si intenten usar una variable `let` abans de la seva declaració.</td></tr></tbody></table>

</div></div></div></div>### Recomanacions

Avui en dia, la millor pràctica és evitar var i utilitzar principalment let (per a variables que es reassignaran) i const (per a valors constants).

- **let (Ús Modern i Recomanat)**
    - Qualsevol variable local que necessiti ser reassignada (canviada de valor).
    - Variables dins de blocs condicionals (if/else) o blocs de funció.
    - Comptadors en bucles (for loop), ja que ofereix un abast de bloc, evitant que la variable comptadora "contamini" l'abast exterior.  
        ```javascript
        for (let i = 0; i < 5; i++) {
          // i només existeix aquí dins
        }
        // console.log(i); // Error
        ```
- **var (Casos d'Ús Heretats)** 
    - Codi antic: Si es treballa amb codi JavaScript heretat o es manté una base de codi antiga.
    - Entorns molt restringits: En entorns on la compatibilitat amb versions molt antigues de JavaScript és obligatòria. (Molt poc freqüent avui dia).

# Variables

Les variables són l'element fonamental de qualsevol llenguatge de programació, inclòs JavaScript. Són contenidors que emmagatzemen dades.

## Declaració de Variables

JavaScript ofereix tres paraules clau principals per declarar variables, cadascuna amb regles d'àmbit (*scope*) i mutabilitat diferents:

### 1. `let`

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-%C3%80mbit%3A-d%27%C3%A0mbit-de-bl">- **Àmbit:** D'àmbit de bloc (la variable només existeix dins del bloc de codi `{}` on està definida).
- **Reassignació:** Es pot reassignar (canviar el seu valor).
- **Redeclaració:** No es pot redeclarar en el mateix àmbit.
    
    <div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-262 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_cfd2263165fe73f2","c_cb55861d8f3a287e",null,"rc_570131b04fd87641",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-262 ng-star-inserted"><span class="ng-tns-c3729132635-262">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-262 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-262 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-262"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-262"></div></div></div>```javascript
    let edat = 30;
    edat = 31; // Vàlid: Reassignació
    // let edat = 32; // Error: No es pot redeclarar
    ```
    
    <div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-262 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_cfd2263165fe73f2","c_cb55861d8f3a287e",null,"rc_570131b04fd87641",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-262"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-262"></div></div></div>

</div>### 2. `const` (Per constants)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-%C3%80mbit%3A-d%27%C3%A0mbit-de-bl-1">- **Àmbit:** D'àmbit de bloc.
- **Reassignació:** **No es pot reassignar.** Ha de ser inicialitzada en la declaració. Ideal per a valors que no han de canviar.
- **Redeclaració:** No es pot redeclarar.
    
    <div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-263 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_cfd2263165fe73f2","c_cb55861d8f3a287e",null,"rc_570131b04fd87641",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-263 ng-star-inserted"><span class="ng-tns-c3729132635-263">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-263 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-263 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-263"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-263"></div></div></div>```javascript
    const PI = 3.14159;
    // PI = 3.14; // Error: No es pot reassignar
    
    // NOTA: Si una const conté un objecte o array, 
    // les seves propietats internes sí es poden modificar.
    const usuari = { nom: 'Anna' };
    usuari.nom = 'Marc'; // Vàlid!
    ```
    
    <div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-263 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_cfd2263165fe73f2","c_cb55861d8f3a287e",null,"rc_570131b04fd87641",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-263"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-263"></div></div></div>

</div>### 3. `var`

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-%C3%80mbit%3A-d%27%C3%A0mbit-de-fu">- **Àmbit:** D'àmbit de funció o global (no d'àmbit de bloc).
- **Hoisting:** El seu comportament d'elevació (*hoisting*) pot generar confusió.
- **Ús:** S'utilitza en codi antic. Avui dia, **es recomana evitar-la** i utilitzar `let` o `const`.

</div>## Tipus de Dades (Tipus Primitius i Estructurals)

JavaScript és un llenguatge de tipus dinàmic, la qual cosa vol dir que no cal especificar el tipus de dades d'una variable en declarar-la, ja que el tipus es determina automàticament en temps d'execució.

### Tipus Primitius (Valors Immutables)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-tipus-descripci%C3%B3-exe"><table style="width: 100%;"><thead><tr><td style="width: 20.7259%;">Tipus</td><td style="width: 49.5959%;">Descripció</td><td style="width: 29.7974%;">Exemple</td></tr></thead><tbody><tr><td style="width: 20.7259%;">**`string`**</td><td style="width: 49.5959%;">Text (cadenes de caràcters).</td><td style="width: 29.7974%;">`let nom = "Jordi";`</td></tr><tr><td style="width: 20.7259%;">**`number`**</td><td style="width: 49.5959%;">Nombres sencers i decimals (punt flotant).</td><td style="width: 29.7974%;">`let quantitat = 10; let preu = 19.99;`</td></tr><tr><td style="width: 20.7259%;">**`boolean`**</td><td style="width: 49.5959%;">Valors lògics: `true` (cert) o `false` (fals).</td><td style="width: 29.7974%;">`let actiu = true;`</td></tr><tr><td style="width: 20.7259%;">**`undefined`**</td><td style="width: 49.5959%;">Valor per defecte d'una variable que s'ha declarat, però a la qual no se li ha assignat un valor.</td><td style="width: 29.7974%;">`let dades;`</td></tr><tr><td style="width: 20.7259%;">**`null`**</td><td style="width: 49.5959%;">Representa l'absència intencional de qualsevol valor o objecte.</td><td style="width: 29.7974%;">`let senseValor = null;`</td></tr><tr><td style="width: 20.7259%;">**`bigint`**</td><td style="width: 49.5959%;">Nombres enters que superen la capacitat màxima de `number`.</td><td style="width: 29.7974%;">`let numGran = 12345678901234567890n;`</td></tr><tr><td style="width: 20.7259%;">**`symbol`**</td><td style="width: 49.5959%;">Valor únic i immutable, sovint utilitzat com a clau d'objecte.</td><td style="width: 29.7974%;">`const id = Symbol('identificador');`</td></tr></tbody></table>

</div>### Tipus Estructurals (Objectes)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-tipus-descripci%C3%B3-exe-1"><table style="width: 100%;"><thead><tr><td style="width: 14.176%;">Tipus</td><td style="width: 50.4247%;">Descripció</td><td style="width: 35.3993%;">Exemple</td></tr></thead><tbody><tr><td style="width: 14.176%;">**`object`**</td><td style="width: 50.4247%;">Col·leccions de dades amb clau-valor. Inclou objectes literals, funcions, dates, i...</td><td style="width: 35.3993%;">`let persona = { nom: "Laura", edat: 25 };`</td></tr><tr><td style="width: 14.176%;">**`array`**</td><td style="width: 50.4247%;">Col·leccions ordenades de valors. (Tècnicament, un tipus especial d'objecte).</td><td style="width: 35.3993%;">`let llista = [1, 'dos', true];`</td></tr></tbody></table>

  
</div>## Operacions Bàsiques amb Variables

Les operacions es realitzen entre variables o valors, i el resultat es pot emmagatzemar en una altra variable.

### 1. Operadors Aritmètics

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-operador-nom-funci%C3%B3-"><table><thead><tr><td>Operador</td><td>Nom</td><td>Funció</td><td>Exemple</td><td>Resultat</td></tr></thead><tbody><tr><td>**`+`**</td><td>Suma</td><td>Suma nombres, o concatena strings.</td><td>`10 + 5` / `'Hola' + ' món'`</td><td>`15` / `'Hola món'`</td></tr><tr><td>**`-`**</td><td>Resta</td><td>Resta nombres.</td><td>`10 - 5`</td><td>`5`</td></tr><tr><td>**`*`**</td><td>Multiplicació</td><td>Multiplica nombres.</td><td>`10 * 5`</td><td>`50`</td></tr><tr><td>**`/`**</td><td>Divisió</td><td>Divideix nombres.</td><td>`10 / 5`</td><td>`2`</td></tr><tr><td>**`%`**</td><td>Mòdul</td><td>Retorna el residu de la divisió.</td><td>`10 % 3`</td><td>`1`</td></tr><tr><td>**`++`**</td><td>Increment</td><td>Augmenta el valor en 1.</td><td>`let a = 5; a++;`</td><td>`a` és `6`</td></tr><tr><td>**`--`**</td><td>Decrement</td><td>Disminueix el valor en 1.</td><td>`let b = 5; b--;`</td><td>`b` és `4`</td></tr></tbody></table>

</div>### 2. Operadors d'Assignació

Permeten realitzar una operació i assignar el resultat a la mateixa variable de manera concisa.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-operador-equivalent-"><table><thead><tr><td>Operador</td><td>Equivalent a</td><td>Exemple</td><td>Resultat</td></tr></thead><tbody><tr><td>**`=`**</td><td>Assignació simple</td><td>`x = 5`</td><td>`x` és `5`</td></tr><tr><td>**`+=`**</td><td>`x = x + y`</td><td>`x += 5`</td><td>Suma i reassigna.</td></tr><tr><td>**`-=`**</td><td>`x = x - y`</td><td>`x -= 5`</td><td>Resta i reassigna.</td></tr><tr><td>**`*=`**</td><td>`x = x * y`</td><td>`x *= 5`</td><td>Multiplica i reassigna.</td></tr><tr><td>**`/=`**</td><td>`x = x / y`</td><td>`x /= 5`</td><td>Divideix i reassigna.</td></tr></tbody></table>

</div>### 3. Operadors de Comparació

Retornen un valor booleà (`true` o `false`).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-operador-nom-funci%C3%B3--1"><table><thead><tr><td>Operador</td><td>Nom</td><td>Funció</td></tr></thead><tbody><tr><td>**`==`**</td><td>Igualtat (Loose)</td><td>Compara només el valor (permet la conversió de tipus).</td></tr><tr><td>**`===`**</td><td>Igualtat Estricta (Strict)</td><td>Compara el valor **i el tipus** (més segur).</td></tr><tr><td>**`!=`**</td><td>Desigualtat (Loose)</td><td>Diferent valor.</td></tr><tr><td>**`!==`**</td><td>Desigualtat Estricta</td><td>Diferent valor o tipus.</td></tr><tr><td>**`>` / `<`**</td><td>Major / Menor que</td><td> </td></tr><tr><td>**`>=` / `<=`**</td><td>Major / Menor o igual que</td><td> </td></tr></tbody></table>

</div>**Regla d'or:** Utilitza sempre la comparació estricta (`===` i `!==`) per evitar errors causats per la conversió automàtica de tipus de JavaScript.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div>

# Variables objecte

## Variables Objecte a JavaScript

A JavaScript, un **objecte** és una col·lecció de propietats no ordenada, on cada propietat té un nom (una clau o *key*) i un valor. És el tipus de dada més complex i fonamental del llenguatge.

Pots pensar en un objecte com un calaix etiquetat que conté informació relacionada sobre una única entitat (una persona, un cotxe, un animal, etc.).

Aquest exemple il·lustra perfectament un objecte literal:

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-292 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2e62cb649f16e09d","c_cb55861d8f3a287e",null,"rc_6f62f7edb30b8d29",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-292 ng-star-inserted"><span class="ng-tns-c3729132635-292">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-292 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-292 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-292"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-292"></div></div></div>```javascript
var animal = {
    id : 345,
    nom : "Gos",
    classe : "Mamífers",
    familia : "Cànids",
    get_taxo : function() {
        return this.classe + " - " + this.familia;
    }
};

```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-292 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2e62cb649f16e09d","c_cb55861d8f3a287e",null,"rc_6f62f7edb30b8d29",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-292"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-292"></div></div></div>### Components d'un Objecte

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietats-%28claus-i-">1. **Propietats (Claus i Valors):**
    
    
    - Són les dades. Estan formades per un **nom (clau)** i un **valor**.
    - **Exemples:** La clau `nom` té el valor `"Gos"`. La clau `id` té el valor `345`.
    - Pots accedir als valors utilitzant la **notació de punt** (`animal.nom`) o la **notació de claudàtors** (`animal['nom']`).
2. **Mètodes (Funcions com a Valors):**
    
    
    - Un mètode és una propietat on el valor és una **funció**.
    - **Exemple:** `get_taxo : function() { ... }` és un mètode.
    - Els mètodes defineixen el *comportament* de l'objecte.
    - Dins d'un mètode, la paraula clau **`this`** es refereix a l'objecte actual (`animal` en aquest cas), permetent accedir a les seves pròpies propietats (p. ex., `this.classe`).

</div>## L'Array com a Objecte

Aquest objecte, l'**Array** (`var especies = ["A. reial", ... ]`) és tècnicament un tipus especial d'objecte a JavaScript, dissenyat per emmagatzemar col·leccions ordenades de valors, amb accés per índex numèric.

```javascript
var especies = ["A. reial", "A. imperial", "A. estepària"]; // Array
```

# JSON

El **JSON (JavaScript Object Notation)** és un format de text lleuger i estàndard utilitzat per a l'intercanvi de dades. És el mètode més comú per enviar dades d'un servidor web a una pàgina web (i viceversa).

JSON es basa en la sintaxi dels objectes literals de JavaScript, però és completament independent del llenguatge i pot ser llegit per qualsevol llenguatge de programació modern (Python, PHP, Java, etc.).

## Característiques del JSON

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-format-de-text%3A-json">1. **Format de Text:** JSON és només text, la qual cosa facilita la seva transmissió a través d'internet.
2. **Estructura Clau-Valor:** La informació s'emmagatzema en parells **clau: valor**.
3. **No Conté Lògica:** JSON només pot emmagatzemar **dades** (objectes, arrays, strings, nombres, booleans i `null`). No pot contenir funcions o mètodes (lògica executable).
4. **Sintaxi Estricta:** Totes les **claus** han d'estar entre **cometes dobles** (`"`).

</div>### Exemple de JSON

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-303 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-json" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_4c4b920e716dcc02","c_cb55861d8f3a287e",null,"rc_4c5eeb0a864aca12",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-303 ng-star-inserted"><span class="ng-tns-c3729132635-303">JSON</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-303 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-303 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-303"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-303"></div></div></div>```javascript
{
    "usuariId": 101,
    "nom": "Maria",
    "interessos": ["programacio", "viatge"],
    "actiu": true
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-303 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_4c4b920e716dcc02","c_cb55861d8f3a287e",null,"rc_4c5eeb0a864aca12",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-303"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-303"></div></div></div>## Ús a JavaScript

JavaScript proporciona l'objecte global **`JSON`** per facilitar la conversió:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-pr"><table style="width: 100%;"><thead><tr><td style="width: 23.3611%;">Mètode</td><td style="width: 43.2529%;">Descripció</td><td style="width: 33.386%;">Propòsit</td></tr></thead><tbody><tr><td style="width: 23.3611%;">**`JSON.stringify()`**</td><td style="width: 43.2529%;">Converteix un **Objecte JavaScript** en una cadena de text JSON.</td><td style="width: 33.386%;">Necessari abans d'**enviar** dades al servidor o d'**emmagatzemar**-ho en localstorage</td></tr><tr><td style="width: 23.3611%;">**`JSON.parse()`**</td><td style="width: 43.2529%;">Converteix una cadena de text **JSON** en un **Objecte JavaScript**.</td><td style="width: 33.386%;">Necessari després de **rebre** dades del servidor per poder utilitzar-les o d'**emmagatzemar**-ho en localstorage</td></tr></tbody></table>

</div>

# Les funcions

Les funcions són l'eina fonamental per estructurar, organitzar i fer reutilitzable qualsevol codi. En essència, una funció és un bloc de codi dissenyat per realitzar una tasca particular. Imagineu-les com a mini-programes que encapsulen lògica, accepten dades (paràmetres) i, opcionalment, produeixen un resultat (valor de retorn). Sense elles, els nostres programes serien simples llistes d'instruccions inmanejables.

JavaScript tracta les funcions com a ciutadans de primera classe (first-class citizens): això vol dir que no només les podeu declarar i cridar, sinó que també les podeu assignar a variables, passar-les com a arguments a altres funcions i retornar-les com a valors, obrint la porta a patrons de disseny potents i complexes.

En aquest capítol explorarem les diverses maneres de crear-les, des de les clàssiques declaracions de funció fins a les concises funcions de fletxa (arrow functions) d'ES6, passant per la flexibilitat de les expressions de funció i les funcions anònimes. També desvetllarem els secrets dels paràmetres, com gestionar arguments opcionals o variables amb els paràmetres rest, i entendrem el concepte crucial de l'àmbit (scope) per escriure codi segur i sense conflictes.

Dominar les funcions no és només aprendre la sintaxi; és aprendre a pensar de manera modular, millorant la claredat, el manteniment i el rendiment de la vostra aplicació. Prepareu-vos per convertir-vos en un arquitecte de codi eficient.

# Funcions en JS

En JavaScript, tens diverses maneres de crear funcions. Les més comunes i importants són les següents, que es divideixen principalment en **declaracions** i **expressions**:

## Declaració de Funció (Function Declaration)

Aquesta és la manera més tradicional i simple de definir una funció. Es fa servir la paraula clau **`function`** seguida del nom de la funció.

### Sintaxi

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-152 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-152 ng-star-inserted"><span class="ng-tns-c3729132635-152">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-152 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-152"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-152">  
</div></div></div>```javascript
function nomDeLaFuncio(parametre1, parametre2) {
  // Cos (body) de la funció
  return parametre1 + parametre2; // Valor que retorna la funció
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-152 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-152"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-152"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>### Característica Clau: Hoisting

Les declaracions de funció són elevades (hoisted) al principi del seu abast. Això significa que **pots cridar la funció abans de declarar-la** al codi.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-153 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-153 ng-star-inserted"><span class="ng-tns-c3729132635-153">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-153 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-153"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-153">  
</div></div></div>```javascript
resultat = sumar(5, 3); // Funciona! (resultat = 8)
console.log(resultat); 

function sumar(a, b) {
  return a + b;
}
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-153 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-153"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-153"></div></div></div>## Expressió de Funció (Function Expression)

En lloc de declarar una funció de forma independent, la funció es crea i s'assigna com un valor a una variable.

### Sintaxi

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-154 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-154 ng-star-inserted"><span class="ng-tns-c3729132635-154">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-154 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-154"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-154">  
</div></div></div>```javascript
const nomDeLaFuncio = function (parametre1, parametre2) {
  return parametre1 * parametre2;
};
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-154 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-154"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-154"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--7"></div>*Nota: La funció assignada pot ser anònima (sense nom, com a l'exemple) o tenir un nom (útil per a la recursió o depuració, però s'accedeix sempre a través del nom de la variable).*

### Característica Clau: No Hoisting

Les expressions de funció **no són elevades**. La variable `nomDeLaFuncio` només està disponible després que la línia de codi d'assignació s'hagi executat.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-155 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-155 ng-star-inserted"><span class="ng-tns-c3729132635-155">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-155 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-155"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-155">  
</div></div></div>```javascript
// resultat = multiplicar(5, 3); // ERROR: ReferenceError, ja que la variable encara no està definida.

const multiplicar = function (a, b) {
  return a * b;
};

resultat = multiplicar(5, 3); // Funciona! (resultat = 15)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-155 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--9" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-155"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-155"></div></div></div>## Funció de Fletxa (Arrow Function)

Introduïdes a ES6, són una sintaxi més concisa per escriure expressions de funció, molt populars avui dia.

### Sintaxi

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-cas-d%27%C3%BAs-sintaxi-de-"><table><thead><tr><td>Cas d'ús</td><td>Sintaxi de Fletxa</td></tr></thead><tbody><tr><td>**Simple (una sola expressió)**</td><td>`const restar = (a, b) => a - b;`</td></tr><tr><td>**Amb bloc de codi**</td><td>`const dividir = (a, b) => { return a / b; };`</td></tr><tr><td>**Un sol paràmetre**</td><td>`const quadrat = a => a * a;`</td></tr><tr><td>**Sense paràmetres**</td><td>`const saluda = () => console.log('Hola');`</td></tr></tbody></table>

</div>### Avantatges i Diferències Clau

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-sintaxi-breu%3A-m%C3%A9s-r%C3%A0">1. **Sintaxi Breu:** Més ràpida d'escriure, especialment per a *callbacks* i funcions d'una sola línia, ja que no cal la paraula `function` ni el `return` explícit.
2. **Gestió de `this` (Context):** A diferència de les altres funcions, les funcions de fletxa **no defineixen el seu propi valor de `this`**. Hereden el `this` del seu entorn de definició (*lexical scope*). Això sol ser un avantatge en el codi orientat a objectes o amb *event handlers*.

</div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-156 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-156 ng-star-inserted"><span class="ng-tns-c3729132635-156">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-156 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-156"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-156">  
</div></div></div>```javascript
// Funció de Fletxa (ús típic com a callback)
const nombres = [1, 2, 3];
const duplicats = nombres.map(n => n * 2); 
// Més concís que: nombres.map(function(n) { return n * 2; });
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-156 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-156"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-156"></div></div></div>## Mètode d'Objecte (Object Method)

Quan una funció es defineix com a propietat d'un objecte, se l'anomena mètode.

### Sintaxi (Forma Concisa)

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-157 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-157 ng-star-inserted"><span class="ng-tns-c3729132635-157">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-157 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-157"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-157">  
</div></div></div>```javascript
const calculadora = {
  // Forma concisa (Equivalent a: sumar: function(a, b) { ... })
  sumar(a, b) {
    return a + b;
  },
  
  restar(a, b) {
    return a - b;
  }
};

console.log(calculadora.sumar(1, 2)); // Sortida: 3
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-157 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_fbde279a08f17b10","c_cb55861d8f3a287e",null,"rc_e73c3cc18c67cb4b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-157"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-157"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--21"></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--22"></div>

# Funcions anònimes

Les **funcions anònimes** a JavaScript són funcions que es defineixen **sense un nom** assignat. Són una part fonamental del llenguatge, ja que permeten tractar les funcions com a valors (objectes de primera classe), cosa que facilita el seu ús com a *callbacks*, tancaments (*closures*) i expressions de funció.

## Característiques i Ús Principal

Una funció anònima no es pot cridar directament pel seu nom, ja que no en té. S'utilitzen principalment en els següents contextos:

### 1. Expressions de Funció (Assignació a Variables)

El mètode més comú és assignar la funció anònima a una variable o constant. Això permet cridar-la posteriorment utilitzant el nom de la variable.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-236 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-236 ng-star-inserted"><span class="ng-tns-c3729132635-236">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-236 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-236 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-236"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-236"></div></div></div>```javascript
// Funció anònima assignada a la variable 'saluda'
const saluda = function() {
    console.log("Hola! Sóc una funció anònima assignada.");
};

saluda(); // Es crida usant el nom de la variable.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-236 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-236"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-236"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>### 2. Funció de Fletxa (Arrow Functions)

Les funcions de fletxa (introduïdes a ES6) són la sintaxi moderna i concisa per crear funcions anònimes.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-237 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-237 ng-star-inserted"><span class="ng-tns-c3729132635-237">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-237 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-237 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-237"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-237"></div></div></div>```
// Funció anònima de fletxa assignada a 'doble'
const doble = (x) => x * 2; 

console.log(doble(5)); // 10

```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-237 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-237"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-237"></div></div></div>## Casos d'Ús Essencials

Les funcions anònimes són indispensables per a diverses tasques clau en JavaScript:

### 1. Funcions de Callback

S'utilitzen quan una funció (A) necessita passar una altra funció (B) com a argument per a ser executada més tard (callback).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-238 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-238 ng-star-inserted"><span class="ng-tns-c3729132635-238">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-238 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-238 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-238"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-238"></div></div></div>```javascript
// Una funció anònima utilitzada com a callback per al mètode map
const nombres = [1, 2, 3];

const resultats = nombres.map(function(n) {
    return n * 10;
});
// resultats és [10, 20, 30]
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-238 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-238"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-238"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--7"></div>### 2. Temporitzadors

Són essencials per als mètodes de temporització de l'objecte `window`, com `setTimeout` i `setInterval`.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-239 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-239 ng-star-inserted"><span class="ng-tns-c3729132635-239">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-239 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-239 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-239"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-239"></div></div></div>```javascript
// La funció s'executarà només una vegada després de 2 segons
setTimeout(function() {
    console.log("Missatge mostrat després d'un temps.");
}, 2000);
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-239 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--9" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-239"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-239"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--10"></div>### 3. Gestors d'Esdeveniments (Event Handlers)

S'utilitzen per definir la lògica que s'ha d'executar quan es produeix un esdeveniment (p. ex., un clic de botó).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-240 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-240 ng-star-inserted"><span class="ng-tns-c3729132635-240">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-240 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-240 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-240"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-240"></div></div></div>```javascript
document.getElementById('elMeuBoto').addEventListener('click', function() {
    alert('Has fet clic al botó!');
    // Aquesta funció anònima només s'executa amb el clic
});
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-240 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-240"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-240"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--13"></div>### 4. IIFE (Immediately Invoked Function Expressions)

Una IIFE és una funció anònima que es defineix i s'executa immediatament. Això és útil per crear un àmbit (scope) privat i evitar que les variables es "fugin" a l'àmbit global.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--14"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-241 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-241 ng-star-inserted"><span class="ng-tns-c3729132635-241">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-241 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-241 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-241"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-241"></div></div></div>```
// S'executa immediatament i 'contador' és privat
(function() {
    var contador = 0; 
    console.log("IIFE executada. El comptador és a 0.");
})(); 

// console.log(contador); // Error: contador no està definit

```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-241 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--15" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_a3f7f4e8f2e476be","c_cb55861d8f3a287e",null,"rc_d31e961b6fd89fcb",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-241"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-241"></div></div></div>## Avantatges

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-avantatge-explicaci%C3%B3"><table style="width: 100%;"><thead><tr><td style="width: 19.535%;">Avantatge</td><td style="width: 80.465%;">Explicació</td></tr></thead><tbody><tr><td style="width: 19.535%;">**Concisió**</td><td style="width: 80.465%;">Especialment amb les funcions de fletxa, redueixen el codi necessari per a operacions simples.</td></tr><tr><td style="width: 19.535%;">**Encapsulació**</td><td style="width: 80.465%;">Són perfectes per als *callbacks* o les IIFE, ja que tanquen la lògica necessària exactament on es necessita, sense contaminar l'àmbit global amb noms de funció innecessaris.</td></tr><tr><td style="width: 19.535%;">**Flexibilitat**</td><td style="width: 80.465%;">Permeten passar la lògica com a dades (arguments) a altres funcions d'ordre superior (`map`, `filter`, `reduce`).</td></tr></tbody></table>

</div>

# Paràmetres en les funcions

## Els paràmetres a les funcions

El pas de paràmetres a una funció en JavaScript es fa de manera flexible. El llenguatge gestiona els paràmetres utilitzant la llista definida en la funció, però també ofereix mecanismes per definir valors per defecte i per capturar un nombre indefinit de paràmetres.

### Paràmetres Obligatoris

En JavaScript, tècnicament, **tots els paràmetres són opcionals** per naturalesa del llenguatge, ja que no hi ha una sintaxi que obligui la seva presència.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-si-un-par%C3%A0metre-es-d">- Si un paràmetre es defineix a la funció però **no es passa** en la crida, el seu valor serà automàticament **`undefined`**.

</div>### Mètode per Simular un Paràmetre Obligatori

Per assegurar que un paràmetre important no s'omet, s'utilitza una comprovació explícita (sovint llançant un error) al principi de la funció.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--13"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-175 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-175 ng-star-inserted"><span class="ng-tns-c3729132635-175">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-175 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-175"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-175">  
</div></div></div>```javascript
function crearUsuari(nom, email) {
  // Comprovació manual per simular l'obligatorietat
  if (nom === undefined) {
    throw new Error("El paràmetre 'nom' és obligatori.");
  }
  if (email === undefined) {
    console.warn("L'email no s'ha proporcionat. Es pot considerar un error o un valor per defecte.");
  }

  // Lògica de la funció...
  console.log(`Usuari creat: ${nom}, Email: ${email}`);
}

// Ús:
crearUsuari("Anna");        // Sortida: Advertència (WARN), Usuari creat: Anna, Email: undefined
// crearUsuari();          // Llança error!
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-175 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--14" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-175"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-175"></div></div></div>### Paràmetres Opcionals (Valors per Defecte)

Els paràmetres opcionals reben un valor per defecte quan el cridador de la funció els omet o els passa explícitament com a `undefined`. Aquesta funcionalitat es va introduir a **ES6 (ECMAScript 2015)**.

#### Sintaxi

Simplement assignes un valor al paràmetre a la declaració de la funció.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--15"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-176 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-176 ng-star-inserted"><span class="ng-tns-c3729132635-176">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-176 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-176 mat-unthemed ng-star-inserted"></button></div></div></div>```javascript
function obtenirPreu(producte, descompte = 0, moneda = 'EUR') {
  const preuFinal = producte.preu * (1 - descompte);
  console.log(`Preu de ${producte.nom}: ${preuFinal.toFixed(2)} ${moneda}`);
}

const llibre = { nom: "La Roda del Temps", preu: 25 };

// Cas 1: Només producte (usa valors per defecte)
obtenirPreu(llibre);
// Sortida: Preu de La Roda del Temps: 25.00 EUR

// Cas 2: Amb descompte (usa moneda per defecte)
obtenirPreu(llibre, 0.15);
// Sortida: Preu de La Roda del Temps: 21.25 EUR

// Cas 3: Tots els paràmetres
obtenirPreu(llibre, 0.20, 'USD');
// Sortida: Preu de La Roda del Temps: 20.00 USD
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-176 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--16" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-176"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-176"></div></div></div>### Paràmetres Indefinits (Paràmetres Rest)

Per gestionar un nombre variable (indefinit) de paràmetres, s'utilitzen els **Paràmetres Rest (`...`)**, una altra característica d'ES6.

La sintaxi `...nomVariable` recull tots els arguments restants que no han estat assignats a paràmetres individuals i els empaqueta en un sol **array**.

#### Sintaxi

El paràmetre rest s'ha de col·locar **al final** de la llista de paràmetres de la funció.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--17"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-177 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-8" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-177 ng-star-inserted"><span class="ng-tns-c3729132635-177">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-177 mat-unthemed ng-star-inserted"></button></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-177"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-177">  
</div></div></div>```javascript
function afegirElements(elementPrincipal, ...elementsAdicionals) {
  console.log(`Element principal: ${elementPrincipal}`);
  
  if (elementsAdicionals.length > 0) {
    console.log("Elements afegits com a array:");
    console.log(elementsAdicionals); // És un Array!
    return elementPrincipal + ' + ' + elementsAdicionals.join(' + ');
  } else {
    return elementPrincipal;
  }
}

// Cas 1: Dos paràmetres
afegirElements('Poma', 'Plàtan');
// elementPrincipal = 'Poma'
// elementsAdicionals = ['Plàtan']

// Cas 2: Diversos paràmetres
const resultat = afegirElements('Cafè', 'Llet', 'Sucre', 'Xocolata');
// elementPrincipal = 'Cafè'
// elementsAdicionals = ['Llet', 'Sucre', 'Xocolata']
console.log(`Resultat final: ${resultat}`);
// Sortida: Resultat final: Cafè + Llet + Sucre + Xocolata
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-177 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--18" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_7ec69e42e24a6c01","c_cb55861d8f3a287e",null,"rc_166854e2cd87143f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-177"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-177"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--19"></div>### L'Objecte `arguments`

Abans d'ES6, els desenvolupadors utilitzaven l'objecte especial **`arguments`** (accessible dins de qualsevol funció) per accedir a tots els paràmetres passats. No obstant això, `arguments` **no és un array real** i és menys flexible que els Paràmetres Rest. Els **Paràmetres Rest (`...`) són la pràctica moderna i preferida** per a gestionar un nombre indefinit d'arguments.

```javascript
function mostrarArguments(a, b) {
  console.log("--- Objecte arguments ---");
  console.log(arguments); 
  // Sortida: Objecte similar a un Array que conté [10, 20, 30, 40]

  console.log(`Primer argument definit (a): ${a}`); 
  // Sortida: Primer argument definit (a): 10
  
  console.log(`Tots els arguments passats:`);
  
  // Per recórrer arguments s'ha d'utilitzar un bucle for tradicional
  for (let i = 0; i < arguments.length; i++) {
    console.log(`Argument ${i}: ${arguments[i]}`);
  }
}

mostrarArguments(10, 20, 30, 40); 

// Si passem menys arguments, el comportament és el mateix:
// mostrarArguments('hola'); 
// Sortida: Argument 0: hola. Arguments[1] seria undefined, però no falla.
```

```javascript
x = findMax(1, 123, 500, 115, 44, 88);

function findMax() {
  var i;
  var max = -Infinity;
  for (i = 0; i < arguments.length; i++) {
    if (arguments[i] > max) {
      max = arguments[i];
    }
  }
  return max;
}
```

Tot i que aquesta funció és vàlida i funcional, el codi modern de JavaScript utilitzaria mètodes més nets i concisos, com els Paràmetres Rest (...) o el mètode Math.max(). El mètode Math.max() pot acceptar una llista d'arguments.

```javascript
function findMaxModern(...nombres) {
  // Els Paràmetres Rest recullen els arguments en un Array real
  return Math.max(...nombres); 
}

let y = findMaxModern(1, 123, 500, 115, 44, 88); 
// y serà 500
```

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--21"></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--22"></div>

# Estructures de control

Les Estructures de Control són els pilars fonamentals de la programació, ja que determinen el flux d'execució del nostre codi JavaScript. Sense elles, un programa només podria executar una llista d'instruccions seqüencials de dalt a baix. Gràcies a les estructures de control, podem fer que el codi prengui decisions i repeteixi tasques. Les dividim en dos grans grups:

**Estructures Condicionals (Decisions)**

Les condicionals permeten al programa escollir un camí a seguir basant-se en si una condició és certa (true) o falsa (false). Són essencials per a la lògica de presa de decisions.

- if...else
- else if
- switch

**Estructures Repetitives o Bucles (Iteració)**

Els bucles permeten executar un bloc de codi repetidament. Això és crucial per processar col·leccions de dades (com arrays) o per realitzar una tasca fins que es compleix una condició:

- for
- while
- do...while
- for...of / for...in

Les estructures de control són, per tant, la força motriu que transforma un simple script en una aplicació dinàmica i funcional.

# Condicionals

Les **Estructures Condicionals** a JavaScript permeten al codi prendre decisions, executant blocs d'instruccions diferents segons si una condició lògica és **certa** (`true`) o **falsa** (`false`). Són la base de qualsevol lògica de presa de decisions en un programa.

Els principals tipus de condicionals a JavaScript són:

## 1. `if`, `else if`, i `else`

Aquesta és l'estructura més comuna i versàtil. Permet executar un bloc de codi si la condició inicial es compleix, i oferir alternatives.

### A. `if` (Condició Única)

Executa el codi només si la condició entre parèntesis és `true`.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-325 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-325 ng-star-inserted"><span class="ng-tns-c3729132635-325">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-325 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-325 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-325"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-325"></div></div></div>```javascript
let edat = 20;

if (edat >= 18) {
  console.log("Pots accedir a la discoteca.");
}
// Sortida: Pots accedir a la discoteca.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-325 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-325"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-325"></div></div></div>### B. `if...else` (Dues Alternatives)

Executa el primer bloc si la condició és `true`, i el bloc `else` si és `false`.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-326 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-326 ng-star-inserted"><span class="ng-tns-c3729132635-326">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-326 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-326 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-326"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-326"></div></div></div>```javascript
let temperatura = 15;

if (temperatura > 25) {
  console.log("Fa calor. Porta roba lleugera.");
} else {
  console.log("Temperatura fresca. Porta jaqueta.");
}
// Sortida: Temperatura fresca. Porta jaqueta.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-326 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-326"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-326"></div></div></div>### C. `if...else if...else` (Múltiples Condicions)

Permet avaluar una seqüència de condicions. El programa executarà el primer bloc la condició del qual sigui `true`, i ignorarà la resta.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-327 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-327 ng-star-inserted"><span class="ng-tns-c3729132635-327">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-327 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-327 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-327"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-327"></div></div></div>```javascript
let puntuacio = 75;

if (puntuacio >= 90) {
  console.log("Excel·lent");
} else if (puntuacio >= 70) {
  console.log("Notable");
} else if (puntuacio >= 50) {
  console.log("Suficient");
} else {
  console.log("Suspès");
}
// Sortida: Notable
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-327 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-327"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-327"></div></div></div>## 2. L'Operador Ternari (`? :`)

És una forma concisa d'escriure una simple estructura `if...else` en una sola línia. És ideal per assignar valors a una variable basant-se en una condició.

### Sintaxi

`condició ? expressió_si_cert : expressió_si_fals`

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-328 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-328 ng-star-inserted"><span class="ng-tns-c3729132635-328">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-328 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-328 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-328"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-328"></div></div></div>```javascript
let hora = 11;
let missatge = (hora < 12) ? "Bon dia" : "Bona tarda";

console.log(missatge);
// Sortida: Bon dia
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-328 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-328"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-328"></div></div></div>## 3. L'Estructura `switch`

El `switch` s'utilitza quan s'ha de comparar una sola expressió (o variable) amb múltiples valors possibles i executar el codi corresponent a cadascun. Sovint és més net i ràpid d'escriure que encadenar molts `if...else if`.

### Sintaxi

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-329 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-329 ng-star-inserted"><span class="ng-tns-c3729132635-329">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-329 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-329 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-329"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-329"></div></div></div>```
let diaSetmana = 3; // On 1=Dilluns, 7=Diumenge

switch (diaSetmana) {
  case 1:
    console.log("Avui és dilluns.");
    break; // Necessari per sortir del 'switch'
  case 5:
    console.log("Avui és divendres! 🎉");
    break;
  case 6:
  case 7:
    console.log("Cap de setmana!");
    break;
  default:
    console.log("Dia feiner no especificat.");
}
// Sortida: Dia feiner no especificat.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-329 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--9" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_8c7783624712ff9b","c_cb55861d8f3a287e",null,"rc_efafad6bcab6a1ee",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-329"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-329"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-case%3A-defineix-un-va">- **`case`:** Defineix un valor possible per a l'expressió.
- **`break`:** És **crucial**. Atura l'execució del `switch` un cop s'ha trobat un cas que coincideix. Si s'omet, el codi continua executant els `case` següents (*fall-through*).
- **`default`:** És opcional. El codi dins de `default` s'executa si cap dels `case` coincideix amb l'expressió.

</div>## Resum d'Ús

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-estructura-%C3%9As-princi"><table style="width: 100%;"><thead><tr><td style="width: 27.1786%;">Estructura</td><td style="width: 36.707%;">Ús Principal</td><td style="width: 36.1144%;">Recomanació</td></tr></thead><tbody><tr><td style="width: 27.1786%;">**`if...else if`**</td><td style="width: 36.707%;">Lògica amb múltiples condicions complexes.</td><td style="width: 36.1144%;">Ús per defecte per a la majoria de decisions.</td></tr><tr><td style="width: 27.1786%;">**Operador Ternari (`? :`)**</td><td style="width: 36.707%;">Assignació condicional de valors a una variable.</td><td style="width: 36.1144%;">Evitar-lo per a lògica molt complexa.</td></tr><tr><td style="width: 27.1786%;">**`switch`**</td><td style="width: 36.707%;">Comparació d'una sola variable amb molts valors discrets.</td><td style="width: 36.1144%;">Quan la comparació és d'igualtat simple (`===`).</td></tr></tbody></table>

</div>

# Bucles

Els **Bucles (Loops)** o estructures repetitives són una eina essencial en JavaScript (i en qualsevol llenguatge de programació) que permet executar un bloc de codi repetidament fins que es compleix una condició de sortida. Són la manera més eficient de processar llistes de dades o realitzar tasques recurrents sense haver d'escriure el mateix codi una vegada i una altra.

A JavaScript existeixen diversos tipus de bucles, cadascun optimitzat per a diferents escenaris:

## 1. Bucles Tradicionals (Basats en Condició o Comptador)

### A. El Bucle `for` (Basat en Comptador)

Aquest és el bucle més utilitzat quan coneixem o podem determinar la quantitat de vegades que s'ha de repetir l'execució.

#### Sintaxi

El `for` requereix tres expressions dins dels parèntesis, separades per punts i comes:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-inicialitzaci%C3%B3%3A-s%27ex">1. **Inicialització:** S'executa una sola vegada a l'inici (normalment es declara i assigna un comptador).
2. **Condició:** S'avalua abans de cada iteració. Si és `true`, el bucle continua. Si és `false`, s'atura.
3. **Expressió Final:** S'executa després de cada iteració (normalment s'incrementa el comptador).

</div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-354 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-354 ng-star-inserted"><span class="ng-tns-c3729132635-354">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-354 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-354 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-354"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-354"></div></div></div>```javascript
for (let i = 0; i < 3; i++) {
  console.log(`Iteració número: ${i}`);
}
// Sortida: 
// Iteració número: 0
// Iteració número: 1
// Iteració número: 2
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-354 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-354"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-354"></div></div></div>### B. El Bucle `while` (Basat en Condició)

El bucle `while` executa un bloc de codi **mentre** una condició lògica es mantingui certa. S'utilitza quan el nombre d'iteracions no es coneix per endavant.

#### Sintaxi

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-355 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-355 ng-star-inserted"><span class="ng-tns-c3729132635-355">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-355 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-355 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-355"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-355"></div></div></div>```javascript
let comptador = 0;

while (comptador < 4) {
  console.log(`El valor és: ${comptador}`);
  comptador++; // Cal assegurar-se que la condició es faci falsa en algun moment!
}
// Sortida: 
// El valor és: 0
// El valor és: 1
// El valor és: 2
// El valor és: 3
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-355 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-355"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-355"></div></div></div>### C. El Bucle `do...while` (Execució Mínima Garantida)

És similar al `while`, però la condició es comprova al final del bucle. Això garanteix que el bloc de codi s'executi **almenys una vegada**, independentment de si la condició inicial és `true` o `false`.

#### Sintaxi

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-356 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-356 ng-star-inserted"><span class="ng-tns-c3729132635-356">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-356 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-356 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-356"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-356"></div></div></div>```javascript
let i = 10;

do {
  console.log(`El bucle s'ha executat una vegada. Valor: ${i}`);
  i++;
} while (i < 5); // La condició és falsa, però s'executa igualment

// Sortida: El bucle s'ha executat una vegada. Valor: 10
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-356 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-356"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-356"></div></div></div>## 2. Bucles Moderns (Específics d'Iteració)

Aquests bucles estan dissenyats per recórrer fàcilment els elements de col·leccions de dades sense haver de gestionar un comptador manual.

### A. El Bucle `for...of` (Iteració de Valors)

Introduït a ES6, és la manera moderna de recórrer els **valors** dels elements iterables (com Arrays, Strings, Maps, Sets, etc.).

#### Sintaxi

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-357 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-357 ng-star-inserted"><span class="ng-tns-c3729132635-357">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-357 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-357 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-357"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-357"></div></div></div>```javascript
const fruites = ["poma", "plàtan", "kiwi"];

for (const fruita of fruites) {
  console.log(`M'agrada la ${fruita}`);
}
// Sortida: 
// M'agrada la poma
// M'agrada el plàtan
// M'agrada el kiwi
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-357 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-357"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-357"></div></div></div>### B. El Bucle `for...in` (Iteració de Propietats d'Objecte)

S'utilitza per iterar sobre els **noms de les propietats (claus)** d'un objecte.

#### Sintaxi

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-358 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-358 ng-star-inserted"><span class="ng-tns-c3729132635-358">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-358 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-358 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-358"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-358"></div></div></div>```javascript
const usuari = { nom: "Laura", edat: 30, ciutat: "Girona" };

for (const clau in usuari) {
  console.log(`${clau}: ${usuari[clau]}`);
}
// Sortida: 
// nom: Laura
// edat: 30
// ciutat: Girona
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-358 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-358"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-358"></div></div></div><p class="callout warning">Si s'utilitza `for...in` amb un array, el que s'obté són els índexs com a cadenes de text (`"0"`, `"1"`, `"2"`, etc.), no els valors de l'array directament.  
</p>

### Mètodes d'Array: `forEach()`

Encara que no és un bucle en el sentit estricte, el mètode **`forEach()`** d'Array és la manera més comuna de recórrer un array. Accepta una funció *callback* que s'executa per a cada element.

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-359 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-359 ng-star-inserted"><span class="ng-tns-c3729132635-359">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-359 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-359 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-359"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-359"></div></div></div>```javascript
const numeros = [10, 20, 30];

numeros.forEach(function(num) {
  console.log(`El número multiplicat per 2 és: ${num * 2}`);
});
// Sortida: 20, 40, 60
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-359 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_41c337b76916b60b","c_cb55861d8f3a287e",null,"rc_7b39132860d6e3a2",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-359"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-359"></div></div></div>El mètode **`forEach()`** és una manera neta i eficient d'iterar sobre els elements d'un array, i és perfecte per a arrays que contenen objectes. A continuació, tenim un exemple que utilitza `forEach()` per recórrer un array d'objectes `persona` i mostra les seves dades:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-398 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_ff4ffa286fc1c0e1","c_cb55861d8f3a287e",null,"rc_3cee3654bfbb9da9",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-398 ng-star-inserted"><span class="ng-tns-c3729132635-398">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-398 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-398 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-398"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-398"></div></div></div>```javascript
// 1. Array d'Objectes 'persona'

const persones = [
  { nom: "Anna", edat: 30, ciutat: "Barcelona" },
  { nom: "Pau", edat: 24, ciutat: "Tarragona" },
  { nom: "Marta", edat: 45, ciutat: "Lleida" }
];

// 2. Ús del forEach()
// Recorrem l'array. Per cada element (que és un objecte 'persona'),
// s'executa la funció de fletxa.

persones.forEach(persona => {
  // 3. Accedim a les propietats de l'objecte actual
  console.log(`Nom: ${persona.nom}, Edat: ${persona.edat}, Viu a: ${persona.ciutat}`);
});
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-398 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_ff4ffa286fc1c0e1","c_cb55861d8f3a287e",null,"rc_3cee3654bfbb9da9",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-398"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-398"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div>Podem fer servir la funció fletxa, més actual i concisa o una funció anònima per fer el callback de `forEach`, la sortida per consola seria el mateix.

```javascript
// 2. Ús del forEach() amb una FUNCIÓ ANÒNIMA CLÀSSICA
persones.forEach(function(persona) {
  // Aquesta funció no té nom i s'executa per cada element.
  
  // 3. Accedim a les propietats de l'objecte 'persona'
  console.log(`Nom: ${persona.nom}, Edat: ${persona.edat}, Viu a: ${persona.ciutat}`);
});
```

#### Sortida a la Consola:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-399 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_ff4ffa286fc1c0e1","c_cb55861d8f3a287e",null,"rc_3cee3654bfbb9da9",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-399"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-399"></div></div></div>```javascript
Nom: Anna, Edat: 30, Viu a: Barcelona
Nom: Pau, Edat: 24, Viu a: Tarragona
Nom: Marta, Edat: 45, Viu a: Lleida
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-399 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--11" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_ff4ffa286fc1c0e1","c_cb55861d8f3a287e",null,"rc_3cee3654bfbb9da9",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-399"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-399"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--12"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--13"></div></div>

# Principals objectes

Aquest capítol us guiarà a través del cor del llenguatge JavaScript: els seus objectes integrats i l'entorn on viuen. Per construir qualsevol aplicació web funcional, no n'hi ha prou amb saber declarar variables i crear funcions; cal entendre com manipular les dades i interactuar amb la finestra del navegador.

D'una banda, explorarem els Objectes Globals Nadius, que proporcionen mètodes i propietats essencials per tractar amb la informació. Des de la gestió de text amb l'objecte String, passant pels càlculs matemàtics avançats a través de l'objecte Math, fins a la manipulació temporal amb Date. També ens endinsarem en l'objecte RegExp, una eina potent i indispensable per buscar patrons complexos dins de les cadenes de text. Com veureu, la flexibilitat de JavaScript rau en la riquesa d'aquests objectes predefinits.

De l'altra banda, examinarem el Model d'Objectes del Navegador (BOM), la vostra interfície directa amb la finestra de l'usuari. L'objecte window és el pare de tots ells i l'àmbit global. A partir d'aquí, coneixerem l'objecte document, que representa la pàgina HTML (el DOM) i us permet manipular-ne el contingut. A més, dominareu objectes clau per a la navegació i l'estat, com ara location (per gestionar l'URL), history (per interactuar amb les sessions de navegació) i navigator i screen (per obtenir informació del dispositiu i la pantalla de l'usuari).

Entendre la relació entre aquests objectes de dades i els objectes del navegador és clau per escriure un codi eficaç, potent i adaptatiu. Prepareu-vos per desbloquejar el potencial complet de JavaScript al món real.

# Objecte String

L'objecte **`String`** de JavaScript és l'eina bàsica per treballar amb text. Encara que normalment utilitzem cadenes com a valors primitius (per exemple, `let text = "exemple"`), JavaScript les tracta internament com a objectes `String` quan apliquem mètodes o accedim a propietats.

És crucial entendre que les cadenes a JavaScript són **immutables**: cap mètode de l'objecte `String` modifica la cadena original; tots retornen una **nova cadena**.

## Propietats Clau de l'Objecte `String`

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3"><table style="width: 100%;"><thead><tr><td style="width: 16.1998%;">Propietat</td><td style="width: 51.3806%;">Descripció</td><td style="width: 21.5733%;">Exemple</td><td style="width: 10.8462%;">Resultat</td></tr></thead><tbody><tr><td style="width: 16.1998%;">**`.length`**</td><td style="width: 51.3806%;">Retorna la **longitud** de la cadena (el nombre de caràcters). És la propietat més utilitzada.</td><td style="width: 21.5733%;">`let s = "Hola"; s.length`</td><td style="width: 10.8462%;">`4`</td></tr><tr><td style="width: 16.1998%;">**`prototype`**</td><td style="width: 51.3806%;">Permet afegir noves propietats i mètodes a l'objecte `String` que estaran disponibles per a totes les cadenes. (Ús avançat, poc recomanat en el codi modern).</td><td style="width: 21.5733%;">`String.prototype.saluda = function() { ... }`</td><td style="width: 10.8462%;">N/A</td></tr><tr><td style="width: 16.1998%;">**`constructor`**</td><td style="width: 51.3806%;">Retorna la funció que va crear l'objecte `String`.</td><td style="width: 21.5733%;">`"text".constructor`</td><td style="width: 10.8462%;">`[Function: String]`</td></tr></tbody></table>

  
</div>## Mètodes Essencials de Manipulació i Cerca

### 1. Cerca i Inclusió

Aquests mètodes ajuden a determinar si una cadena conté un text específic i, si és així, on es troba.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex"><table style="width: 100%;"><thead><tr><td style="width: 24.9106%;">Mètode</td><td style="width: 34.9261%;">Descripció</td><td style="width: 29.1979%;">Exemple</td><td style="width: 10.9654%;">Resultat</td></tr></thead><tbody><tr><td style="width: 24.9106%;">**`.includes(str)`**</td><td style="width: 34.9261%;">Comprova si la cadena conté la subcadena `str`. Retorna **`true`** o **`false`**.</td><td style="width: 29.1979%;">`'gat.jpg'.includes('.jpg')`</td><td style="width: 10.9654%;">`true`</td></tr><tr><td style="width: 24.9106%;">**`.indexOf(str)`**</td><td style="width: 34.9261%;">Retorna la posició (índex) de la **primera ocurrència** de `str`, o `-1` si no es troba.</td><td style="width: 29.1979%;">`'banana'.indexOf('na')`</td><td style="width: 10.9654%;">`2`</td></tr><tr><td style="width: 24.9106%;">**`.lastIndexOf(str)`**</td><td style="width: 34.9261%;">Retorna la posició de l'**última ocurrència** de `str`.</td><td style="width: 29.1979%;">`'banana'.lastIndexOf('na')`</td><td style="width: 10.9654%;">`4`</td></tr><tr><td style="width: 24.9106%;">**`.startsWith(str)`**</td><td style="width: 34.9261%;">Comprova si la cadena comença amb `str`.</td><td style="width: 29.1979%;">`'web.html'.startsWith('web')`</td><td style="width: 10.9654%;">`true`</td></tr><tr><td style="width: 24.9106%;">**`.endsWith(str)`**</td><td style="width: 34.9261%;">Comprova si la cadena acaba amb `str`.</td><td style="width: 29.1979%;">`'web.html'.endsWith('.com')`</td><td style="width: 10.9654%;">`false`</td></tr><tr><td style="width: 24.9106%;">**`.search(str/regexp)`**</td><td style="width: 34.9261%;">Cerca i retorna l'índex de la **primera coincidència**. Pot acceptar una Expressió Regular (`RegExp`).</td><td style="width: 29.1979%;">`'A12B34'.search(/[0-9]/)`</td><td style="width: 10.9654%;">`1` (la posició del primer número)</td></tr></tbody></table>

</div>### 2. Extracció i Transformació de Subcadenes

Aquests mètodes permeten obtenir un fragment de la cadena original.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-1"><table style="width: 100%;"><thead><tr><td style="width: 24.3147%;">Mètode</td><td style="width: 36.1241%;">Descripció</td><td style="width: 27.6423%;">Exemple</td><td style="width: 11.919%;">Resultat</td></tr></thead><tbody><tr><td style="width: 24.3147%;">**`.slice(x, y)`**</td><td style="width: 36.1241%;">Extreu una part des de l'índex `x` fins a l'índex `y` (excloent `y`). Accepta índexs negatius (que compten des del final).</td><td style="width: 27.6423%;">`'JavaScript'.slice(4, 9)`</td><td style="width: 11.919%;">`'Scrip'`</td></tr><tr><td style="width: 24.3147%;">**`.substring(x, y)`**</td><td style="width: 36.1241%;">Similar a `slice()`, però tracta els índexs negatius o superiors al final com `0` o `length` respectivament.</td><td style="width: 27.6423%;">`'JavaScript'.substring(0, 4)`</td><td style="width: 11.919%;">`'Java'`</td></tr><tr><td style="width: 24.3147%;">**`.substr(x, y)`** *(Obsolet)*</td><td style="width: 36.1241%;">Extreu des de l'índex `x`, un total de `y` caràcters.</td><td style="width: 27.6423%;">`'JavaScript'.substr(4, 5)`</td><td style="width: 11.919%;">`'Scrip'`</td></tr><tr><td style="width: 24.3147%;">**`.charAt(x)`**</td><td style="width: 36.1241%;">Retorna el caràcter a la posició `x`.</td><td style="width: 27.6423%;">`'Hola'.charAt(1)`</td><td style="width: 11.919%;">`'o'`</td></tr></tbody></table>

</div>### 3. Modificació i Format

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-2"><table style="width: 100%;"><thead><tr><td style="width: 24.553%;">Mètode</td><td style="width: 37.8936%;">Descripció</td><td style="width: 19.3174%;">Exemple</td><td style="width: 18.236%;">Resultat</td></tr></thead><tbody><tr><td style="width: 24.553%;">**`.concat(str)`**</td><td style="width: 37.8936%;">Uneix la cadena original amb la cadena `str`. (L'operador `+` és la forma més habitual).</td><td style="width: 19.3174%;">`'Bon'.concat(' dia!')`</td><td style="width: 18.236%;">`'Bon dia!'`</td></tr><tr><td style="width: 24.553%;">**`.repeat(x)`**</td><td style="width: 37.8936%;">Retorna una nova cadena repetida `x` vegades.</td><td style="width: 19.3174%;">`'ha'.repeat(3)`</td><td style="width: 18.236%;">`'hahaha'`</td></tr><tr><td style="width: 24.553%;">**`.replace(str1, str2)`**</td><td style="width: 37.8936%;">Reemplaça la **primera ocurrència** de `str1` per `str2`. (Es necessita una `RegExp` amb el flag global `/g` per reemplaçar-ho tot).</td><td style="width: 19.3174%;">`'plata i or'.replace(' ', ' o ')`</td><td style="width: 18.236%;">`'plata o or'`</td></tr><tr><td style="width: 24.553%;">**`.match(regexp)`**</td><td style="width: 37.8936%;">Cerca dins la cadena utilitzant una Expressió Regular (`RegExp`) i retorna les coincidències en un `Array`.</td><td style="width: 19.3174%;">`'a1b2'.match(/[a-z]/g)`</td><td style="width: 18.236%;">`['a', 'b']`</td></tr><tr><td style="width: 24.553%;">**`.split(car)`**</td><td style="width: 37.8936%;">Divideix la cadena en un **Array** de subcadenes usant `car` com a separador.</td><td style="width: 19.3174%;">`'casa,llibre,gos'.split(',')`</td><td style="width: 18.236%;">`['casa', 'llibre', 'gos']`</td></tr><tr><td style="width: 24.553%;">**`.toLowerCase()`**</td><td style="width: 37.8936%;">Converteix tots els caràcters a minúscules.</td><td style="width: 19.3174%;">`'HELLO'.toLowerCase()`</td><td style="width: 18.236%;">`'hello'`</td></tr><tr><td style="width: 24.553%;">**`.toUpperCase()`**</td><td style="width: 37.8936%;">Converteix tots els caràcters a majúscules.</td><td style="width: 19.3174%;">`'hello'.toUpperCase()`</td><td style="width: 18.236%;">`'HELLO'`</td></tr><tr><td style="width: 24.553%;">**`.trim()`**</td><td style="width: 37.8936%;">Elimina els espais en blanc (inclou tabulacions i salts de línia) del principi i del final de la cadena.</td><td style="width: 19.3174%;">`' \t text \n '.trim()`</td><td style="width: 18.236%;">`'text'`</td></tr><tr><td style="width: 24.553%;">**`.toString()`/`.valueOf()`**</td><td style="width: 37.8936%;">Aquests mètodes s'utilitzen per obtenir la representació de la cadena com a valor primitiu, especialment útil si la variable original era un objecte `String` explícit.</td><td style="width: 19.3174%;">N/A</td><td style="width: 18.236%;">N/A</td></tr></tbody></table>

</div>

# Objecte number

L'objecte **`Number`** de JavaScript és l'encarregat de gestionar totes les dades numèriques. A diferència d'altres llenguatges, JavaScript inicialment només tenia **un sol tipus** per a tots els números: el de **doble precisió de 64 bits (IEEE 754)**, la qual cosa implica que tots els nombres (enters i decimals) es guarden com a coma flotant. Recentment, s'ha afegit **`BigInt`** per a enters extremadament grans, però `Number` continua sent l'estàndard.

## Format i Notació de Números

Els nombres es poden representar en diferents bases numèriques, facilitant la interacció amb dades binàries o codificacions de colors (hexadecimal).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-notaci%C3%B3-prefix-base-"><table><thead><tr><td>Notació</td><td>Prefix</td><td>Base (Radix)</td><td>Exemple</td><td>Resultat Decimal</td></tr></thead><tbody><tr><td>**Decimal**</td><td>Cap</td><td>10</td><td>`42`</td><td>42</td></tr><tr><td>**Binari**</td><td>`0b`</td><td>2</td><td>`0b1010`</td><td>10</td></tr><tr><td>**Octal**</td><td>`0o`</td><td>8</td><td>`0o70`</td><td>56</td></tr><tr><td>**Hexadecimal**</td><td>`0x`</td><td>16</td><td>`0xFF`</td><td>255</td></tr></tbody></table>

</div>### Conversió a Altres Bases: Mètode `toString()`

El mètode `toString()` és crucial per convertir un nombre en la seva representació de cadena en una base diferent, passant la base com a paràmetre (el *radix*).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-433 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_67c1d45600732eec","c_cb55861d8f3a287e",null,"rc_b2985f8d4f9e2ffd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-433 ng-star-inserted"><span class="ng-tns-c3729132635-433">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-433 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-433 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-433"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-433">  
</div></div></div>```javascript
var num = 76;
console.log(num.toString(16)); // "4c" (76 en hexadecimal)
console.log(num.toString(8));  // "114" (76 en octal)
console.log(num.toString(2));  // "1001100" (76 en binari)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-433 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_67c1d45600732eec","c_cb55861d8f3a287e",null,"rc_b2985f8d4f9e2ffd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-433"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-433"></div></div></div>## Valors Especials de `Number`

Aquests valors actuen com a constants estàtiques de l'objecte `Number` i representen condicions matemàtiques especials.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-valor-descripci%C3%B3-exe"><table style="width: 100%;"><thead><tr><td style="width: 25.8667%;">Valor</td><td style="width: 41.7138%;">Descripció</td><td style="width: 8.22408%;">Exemple</td><td style="width: 24.1955%;">Explicació</td></tr></thead><tbody><tr><td style="width: 25.8667%;">**`Infinity`**</td><td style="width: 41.7138%;">Valor que representa l'infinit matemàtic (positiu o negatiu). S'obté quan el resultat d'un càlcul supera la precisió màxima representable.</td><td style="width: 8.22408%;">`1 / 0`</td><td style="width: 24.1955%;">Resultat: `Infinity`</td></tr><tr><td style="width: 25.8667%;">**`NaN`**</td><td style="width: 41.7138%;">**Not a Number** (No és un número). Indica que el valor no és un número legal, sovint resultat d'operacions matemàtiques invàlides (p. ex., dividir `0 / 0` o intentar sumar un número i un text no numèric).</td><td style="width: 8.22408%;">`0 / 0`</td><td style="width: 24.1955%;">Resultat: `NaN`</td></tr><tr><td style="width: 25.8667%;">**`Number.MAX_SAFE_INTEGER`**</td><td style="width: 41.7138%;">El nombre enter més gran que JavaScript pot garantir la seva precisió sense errors.</td><td style="width: 8.22408%;">`9007199254740991`</td><td style="width: 24.1955%;">Útil per a evitar pèrdues de dades en IDs molt grans (per això existeix `BigInt`).</td></tr></tbody></table>

</div>## Mètodes Estàtics de l'Objecte `Number` (Comprovacions)

Aquests mètodes es criden directament sobre l'objecte `Number` (per exemple, `Number.isInteger()`) i s'utilitzen per fer validacions.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex"><table style="width: 100%;"><thead><tr><td style="width: 28.2479%;">Mètode</td><td style="width: 32.6579%;">Descripció</td><td style="width: 21.5665%;">Exemple</td><td style="width: 17.5277%;">Resultat</td></tr></thead><tbody><tr><td style="width: 28.2479%;">**`Number.isInteger(value)`**</td><td style="width: 32.6579%;">Comprova si el valor és un número enter.</td><td style="width: 21.5665%;">`Number.isInteger(3.0)`</td><td style="width: 17.5277%;">`true`</td></tr><tr><td style="width: 28.2479%;">**`Number.isFinite(value)`**</td><td style="width: 32.6579%;">Comprova si el valor és un número finit (no `Infinity` ni `-Infinity`).</td><td style="width: 21.5665%;">`Number.isFinite(1 / 0)`</td><td style="width: 17.5277%;">`false`</td></tr><tr><td style="width: 28.2479%;">**`Number.isNaN(value)`**</td><td style="width: 32.6579%;">Comprova si el valor és exactament `NaN`. (És millor que la funció global `isNaN()`).</td><td style="width: 21.5665%;">`Number.isNaN("hola")`</td><td style="width: 17.5277%;">`false` (la funció global retornaria `true`)</td></tr></tbody></table>

</div>## Mètodes d'Instància (Format i Conversió)

Aquests mètodes es criden sobre una instància de número (per exemple, `num.toFixed()`) i retornen una representació en cadena del número.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-1"><table style="width: 100%;"><thead><tr><td style="width: 19.5471%;">Mètode</td><td style="width: 43.1466%;">Descripció</td><td style="width: 24.4394%;">Exemple</td><td style="width: 12.8669%;">Resultat</td></tr></thead><tbody><tr><td style="width: 19.5471%;">**`.toFixed(n)`**</td><td style="width: 43.1466%;">Formata el número amb una precisió decimal de `n` dígits. **Retorna una cadena de text.**</td><td style="width: 24.4394%;">`let preu = 12.3456; preu.toFixed(2)`</td><td style="width: 12.8669%;">`"12.35"`</td></tr><tr><td style="width: 19.5471%;">**`.toPrecision(n)`**</td><td style="width: 43.1466%;">Formata el número amb un nombre total de `n` dígits (part entera i decimal). **Retorna una cadena de text.**</td><td style="width: 24.4394%;">`let x = 123.456; x.toPrecision(4)`</td><td style="width: 12.8669%;">`"123.5"`</td></tr><tr><td style="width: 19.5471%;">**`.toExponential(x)`**</td><td style="width: 43.1466%;">Representa el número en notació exponencial.</td><td style="width: 24.4394%;">`(123000).toExponential(2)`</td><td style="width: 12.8669%;">`"1.23e+5"`</td></tr></tbody></table>

</div>### Conversió de Strings a Números

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-funci%C3%B3-descripci%C3%B3-ex"><table style="width: 100%;"><thead><tr><td style="width: 20.5006%;">Funció</td><td style="width: 43.7522%;">Descripció</td><td style="width: 28.3575%;">Exemple</td><td style="width: 7.38975%;">Resultat</td></tr></thead><tbody><tr><td style="width: 20.5006%;">**`parseInt(string)`**</td><td style="width: 43.7522%;">Converteix una cadena al seu equivalent **enter**. S'atura quan troba un caràcter no numèric.</td><td style="width: 28.3575%;">`parseInt("10.5 metres")`</td><td style="width: 7.38975%;">`10`</td></tr><tr><td style="width: 20.5006%;">**`parseFloat(string)`**</td><td style="width: 43.7522%;">Converteix una cadena al seu equivalent **decimal** (punt flotant).</td><td style="width: 28.3575%;">`parseFloat("10.5 metres")`</td><td style="width: 7.38975%;">`10.5`</td></tr><tr><td style="width: 20.5006%;">**`Number(value)`**</td><td style="width: 43.7522%;">Funció constructora que intenta convertir qualsevol valor al tipus `Number`.</td><td style="width: 28.3575%;">`Number(true)`</td><td style="width: 7.38975%;">`1`</td></tr></tbody></table>

</div>

# El mètode valueOf

El mètode **`valueOf()`** a JavaScript és un mètode universal present en la majoria dels objectes integrats del llenguatge. El seu propòsit és retornar el **valor primitiu** de l'objecte sobre el qual s'invoca.

En termes pràctics, s'utilitza principalment quan JavaScript necessita un valor primitiu (com un nombre o una cadena) a partir d'un objecte, per exemple, durant certes operacions de comparació o conversió de tipus.

## Funcionament de `valueOf()` en Tipus Específics

Tot i que tots els objectes tenen el mètode `valueOf()`, el seu ús és més notable en els tipus que tenen un equivalent primitiu:

### 1. Objecte `String`

Retorna la cadena de text primitiva:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-448 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-448 ng-star-inserted"><span class="ng-tns-c3729132635-448">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-448 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-448 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-448"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-448"></div></div></div>```javascript
let strObjecte = new String("Hola"); // Creació explícita de l'objecte String
let valorPrimitiu = strObjecte.valueOf();

console.log(valorPrimitiu);    // Sortida: "Hola"
console.log(typeof valorPrimitiu); // Sortida: "string" 
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-448 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-448"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-448"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>### 2. Objecte `Number`

Retorna el valor numèric primitiu:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-449 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-449 ng-star-inserted"><span class="ng-tns-c3729132635-449">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-449 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-449 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-449"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-449"></div></div></div>```javascript
let numObjecte = new Number(42); // Creació explícita de l'objecte Number
let valorPrimitiu = numObjecte.valueOf();

console.log(valorPrimitiu);    // Sortida: 42
console.log(typeof valorPrimitiu); // Sortida: "number"
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-449 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-449"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-449"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"></div>### 3. Objecte `Date`

Retorna el valor primitiu del temps, que és el nombre de mil·lisegons des de l'època UNIX (1 de gener de 1970).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-450 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-450 ng-star-inserted"><span class="ng-tns-c3729132635-450">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-450 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-450 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-450"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-450"></div></div></div>```javascript
let data = new Date();
let milisegons = data.valueOf(); 

console.log(milisegons); // Sortida: Un nombre gran (mil·lisegons actuals)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-450 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-450"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-450"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div>### 4. Objectes Personalitzats

Es pot sobreescriure el mètode `valueOf()` en els teus propis objectes per definir com es representen com a valor primitiu:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-451 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-451 ng-star-inserted"><span class="ng-tns-c3729132635-451">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-451 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-451 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-451"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-451"></div></div></div>```javascript
const punt = {
  x: 10,
  y: 20,
  valueOf: function() {
    return this.x + this.y; // El valor primitiu d'un punt és la suma de les seves coordenades
  }
};

console.log(punt + 5); // JavaScript crida punt.valueOf() -> 30 + 5
// Sortida: 35
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-451 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_59c44552efb77f6f","c_cb55861d8f3a287e",null,"rc_a76db3813755656e",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-451"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-451"></div></div></div>## `valueOf()` vs. `toString()`

Quan JavaScript necessita convertir un objecte a un primitiu, segueix una jerarquia:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-si-espera-un-valor-n">1. Si espera un valor **numèric**, crida principalment **`valueOf()`**.
2. Si espera una **cadena de text**, crida principalment **`toString()`**.

</div>Si el mètode preferit no retorna un primitiu o no està disponible, JavaScript prova l'altre mètode. En molts objectes primitius embolcallats (`Number`, `Boolean`), tant `valueOf()` com `toString()` retornen resultats que reflecteixen la seva naturalesa.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11"></div>

# Objecte Date

L'objecte **`Date`** de JavaScript és un objecte essencial utilitzat per treballar amb dates i hores. Aquest objecte es basa en el concepte de **Temps Unix** (o Època Unix), que compta els **mil·lisegons** transcorreguts des de la mitjanit de l'1 de gener de 1970 (UTC).

## Creació i Instanciació de l'Objecte `Date`

Per crear una nova instància de `Date`, sempre s'utilitza l'operador **`new Date()`**. Els constructors accepten diferents formats:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-format-del-construct"><table><thead><tr><td>Format del Constructor</td><td>Descripció</td><td>Exemple</td></tr></thead><tbody><tr><td>**Sense arguments**</td><td>Crea un objecte amb la data i hora **actuals** del sistema.</td><td>`var data = new Date();`</td></tr><tr><td>**Mil·lisegons**</td><td>Crea una data que representa els mil·lisegons transcorreguts des de l'1/1/1970.</td><td>`var data = new Date(34885453664);`</td></tr><tr><td>**String de Data**</td><td>Crea una data a partir d'una cadena de data llegible.</td><td>`data = new Date('2016/05/23');`</td></tr><tr><td>**Arguments Numèrics**</td><td>Permet especificar l'any, el mes, el dia, etc. (la manera més precisa).</td><td>`data = new Date(2016, 5, 23, 12, 15, 24, 220);`</td></tr></tbody></table>

</div><p class="callout warning">**Atenció.** El Mes Comença per Zero (0)</p>

En la construcció amb arguments numèrics, recorda que els **mesos** es compten de 0 a 11:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-0-%E2%86%92-gener-5-%E2%86%92-juny-1">- `0` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> Gener
- `5` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> Juny
- `11` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> Desembre

</div>Per tant, `new Date(2016, 5, 23, ...)` crea la data **23 de juny de 2016**.

## Mètodes per Obtenir Components de la Data

Aquests mètodes permeten obtenir parts específiques de la data i l'hora. Existeixen dues versions per a gairebé tots: la versió **local** (basada en la zona horària de l'usuari) i la versió **UTC** (Temps Universal Coordinat, sense tenir en compte la zona horària).

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-local-retorna"><table><thead><tr><td>Mètode Local</td><td>Retorna</td><td>Rang</td><td>Explicació</td></tr></thead><tbody><tr><td>**`getFullYear()`**</td><td>L'any (4 dígits).</td><td>Any</td><td> </td></tr><tr><td>**`getMonth()`**</td><td>El mes.</td><td>0 - 11</td><td>**0 = Gener, 11 = Desembre.**</td></tr><tr><td>**`getDate()`**</td><td>El dia del mes.</td><td>1 - 31</td><td> </td></tr><tr><td>**`getDay()`**</td><td>El dia de la setmana.</td><td>0 - 6</td><td>**0 = Diumenge, 6 = Dissabte.**</td></tr><tr><td>**`getHours()`**</td><td>L'hora.</td><td>0 - 23</td><td> </td></tr><tr><td>**`getTime()`**</td><td>Els mil·lisegons des de 1/1/1970.</td><td>Nombre</td><td>Usat per calcular diferències de temps.</td></tr></tbody></table>

</div>**Exemple d'Obtenció i Format:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-463 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ee7c4e3b9db9d71","c_cb55861d8f3a287e",null,"rc_77e0ea76b2d2aaa5",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-463 ng-star-inserted"><span class="ng-tns-c3729132635-463">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-463 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-463 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-463"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-463">  
</div></div></div>```javascript
let dataNadal = new Date(2025, 11, 25); // Desembre és el mes 11
let any = dataNadal.getFullYear();
let mes = dataNadal.getMonth() + 1; // +1 per obtenir 1-12
let dia = dataNadal.getDate();

console.log(`Nadal cau el: ${dia}/${mes}/${any}`); 
// Sortida: Nadal cau el: 25/12/2025
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-463 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ee7c4e3b9db9d71","c_cb55861d8f3a287e",null,"rc_77e0ea76b2d2aaa5",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-463"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-463"></div></div></div>## Mètodes per Modificar Components de la Data

Els mètodes **`set...`** permeten canviar els components d'una instància de `Date` existent, actualitzant-la.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem"><table style="width: 100%;"><thead><tr><td style="width: 29.7889%;">Mètode</td><td style="width: 33.7391%;">Propòsit</td><td style="width: 36.472%;">Exemple</td></tr></thead><tbody><tr><td style="width: 29.7889%;">**`setFullYear(any, mes, dia)`**</td><td style="width: 33.7391%;">Estableix l'any (i opcionalment mes i dia).</td><td style="width: 36.472%;">`data.setFullYear(2026);`</td></tr><tr><td style="width: 29.7889%;">**`setMonth(mes)`**</td><td style="width: 33.7391%;">Estableix el mes (recorda 0-11).</td><td style="width: 36.472%;">`data.setMonth(0);` (Gener)</td></tr><tr><td style="width: 29.7889%;">**`setTime(milisegons)`**</td><td style="width: 33.7391%;">Canvia la data a una hora específica a partir dels mil·lisegons.</td><td style="width: 36.472%;">`data.setTime(0);` (Estableix la data a 1/1/1970 UTC)</td></tr></tbody></table>

</div>## Mètodes de Conversió (Format Lector)

Aquests mètodes són útils per formatar la data en una cadena de text llegible, sovint tenint en compte les convencions locals.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex"><table style="width: 100%;"><thead><tr><td style="width: 26.2084%;">Mètode</td><td style="width: 38.5115%;">Descripció</td><td style="width: 35.2801%;">Exemple</td></tr></thead><tbody><tr><td style="width: 26.2084%;">**`.toString()`**</td><td style="width: 38.5115%;">Converteix l'objecte data a una cadena, incloent la zona horària.</td><td style="width: 35.2801%;">`data.toString()` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> `Thu Sep 25 2025 12:30:06 GMT+0200 (CEST)`</td></tr><tr><td style="width: 26.2084%;">**`.toLocaleDateString()`**</td><td style="width: 38.5115%;">Formata només la part de la data utilitzant el format local de l'usuari (p. ex., 25/9/2025 a Catalunya).</td><td style="width: 35.2801%;">`data.toLocaleDateString()`</td></tr><tr><td style="width: 26.2084%;">**`.toLocaleTimeString()`**</td><td style="width: 38.5115%;">Formata només la part de l'hora utilitzant el format local.</td><td style="width: 35.2801%;">`data.toLocaleTimeString()`</td></tr><tr><td style="width: 26.2084%;">**`.toLocaleString()`**</td><td style="width: 38.5115%;">Combina data i hora amb format local.</td><td style="width: 35.2801%;">`data.toLocaleString()`</td></tr><tr><td style="width: 26.2084%;">**`.toISOString()`**</td><td style="width: 38.5115%;">Converteix la data al format estàndard ISO 8601 (utilitzat per intercanvi de dades entre sistemes).</td><td style="width: 35.2801%;">`data.toISOString()` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> `"2025-09-25T10:30:06.000Z"`</td></tr></tbody></table>

</div>## Mètodes Estàtics Importants (Sense Instanciació)

Aquests mètodes es criden directament sobre l'objecte `Date` sense necessitat de crear una instància.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem-1"><table style="width: 100%;"><thead><tr><td style="width: 25.2571%;">Mètode</td><td style="width: 54.9574%;">Propòsit</td><td style="width: 19.7855%;">Exemple</td></tr></thead><tbody><tr><td style="width: 25.2571%;">**`Date.now()`**</td><td style="width: 54.9574%;">Retorna el nombre de mil·lisegons actuals des de l'1/1/1970. (El mètode preferit per mesurar el temps).</td><td style="width: 19.7855%;">`let inici = Date.now();`</td></tr><tr><td style="width: 25.2571%;">**`Date.parse(string)`**</td><td style="width: 54.9574%;">Intenta analitzar una cadena de data i retorna els mil·lisegons corresponents.</td><td style="width: 19.7855%;">`Date.parse('2025-01-01')`</td></tr></tbody></table>

</div>

# Objecte Math

L'objecte **`Math`** de JavaScript és un objecte global integrat que s'utilitza per realitzar operacions i constants matemàtiques. La clau és que, a diferència d'altres objectes com `Date` o `String`, **`Math` no és un constructor**. No es pot crear una nova instància (no es fa servir `new Math()`). Tots els seus mètodes i propietats són **estàtics** i s'utilitzen directament.

## Propietats de `Math`

L'objecte `Math` emmagatzema les constants matemàtiques de major utilitat amb una alta precisió. S'accedeix a elles directament.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3"><table style="width: 100%;"><thead><tr><td style="width: 25.6257%;">Propietat</td><td style="width: 28.3753%;">Descripció</td><td style="width: 31.2194%;">Exemple d'Ús</td><td style="width: 14.7795%;">Resultat (Aprox.)</td></tr></thead><tbody><tr><td style="width: 25.6257%;">**`Math.PI`**</td><td style="width: 28.3753%;">El famós nombre Pi (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">π</span></span></span></span></span>).</td><td style="width: 31.2194%;">`Math.PI * 2` (Circumferència)</td><td style="width: 14.7795%;">3.14159...</td></tr><tr><td style="width: 25.6257%;">**`Math.E`**</td><td style="width: 28.3753%;">El nombre d'Euler (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">e</span></span></span></span></span>).</td><td style="width: 31.2194%;">`Math.E`</td><td style="width: 14.7795%;">2.71828...</td></tr><tr><td style="width: 25.6257%;">**`Math.SQRT2`**</td><td style="width: 28.3753%;">Arrel quadrada de 2 (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="svg-align"><span class="mord">2</span></span><span class=""><span class="hide-tail">![]()</span></span></span><span class="vlist-s">​</span></span></span></span></span></span></span></span>).</td><td style="width: 31.2194%;">`Math.SQRT2`</td><td style="width: 14.7795%;">1.41421...</td></tr><tr><td style="width: 25.6257%;">**`Math.LN2`**</td><td style="width: 28.3753%;">Logaritme natural (base <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">e</span></span></span></span></span>) de 2.</td><td style="width: 31.2194%;">`Math.LN2`</td><td style="width: 14.7795%;">0.69314...</td></tr></tbody></table>

</div>## Mètodes de Càlcul i Aritmètica

Aquests mètodes permeten efectuar operacions algebraiques i trigonomètriques.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex"><table style="width: 100%;"><thead><tr><td style="width: 21.8161%;">Mètode</td><td style="width: 39.3281%;">Descripció</td><td style="width: 33.7306%;">Exemple</td><td style="width: 5.12515%;">Resultat</td></tr></thead><tbody><tr><td style="width: 21.8161%;">**`Math.abs(x)`**</td><td style="width: 39.3281%;">Retorna el **valor absolut** de <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span>.</td><td style="width: 33.7306%;">`Math.abs(-5)`</td><td style="width: 5.12515%;">`5`</td></tr><tr><td style="width: 21.8161%;">**`Math.pow(x, y)`**</td><td style="width: 39.3281%;">Retorna <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> elevat a la potència <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">y</span></span></span></span></span> (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist"><span class=""><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">y</span></span></span></span></span></span></span></span></span></span></span></span>).</td><td style="width: 33.7306%;">`Math.pow(2, 3)` (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">2<span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist"><span class=""><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span></span>)</td><td style="width: 5.12515%;">`8`</td></tr><tr><td style="width: 21.8161%;">**`Math.sqrt(x)`**</td><td style="width: 39.3281%;">Retorna l'arrel quadrada de <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist"><span class="svg-align"><span class="mord"><span class="mord mathnormal">x</span></span></span><span class=""><span class="hide-tail">![]()</span></span></span><span class="vlist-s">​</span></span></span></span></span></span></span></span>).</td><td style="width: 33.7306%;">`Math.sqrt(25)`</td><td style="width: 5.12515%;">`5`</td></tr><tr><td style="width: 21.8161%;">**`Math.exp(x)`**</td><td style="width: 39.3281%;">Retorna el valor d'Euler elevat a <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> (<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist"><span class=""><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span></span>).</td><td style="width: 33.7306%;">`Math.exp(1)`</td><td style="width: 5.12515%;"><span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">2.71828...</span></span></span></span></span> (`Math.E`)</td></tr><tr><td style="width: 21.8161%;">**`Math.log(x)`**</td><td style="width: 39.3281%;">Retorna el logaritme natural (base <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">e</span></span></span></span></span>) de <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span>.</td><td style="width: 33.7306%;">`Math.log(Math.E)`</td><td style="width: 5.12515%;">`1`</td></tr><tr><td style="width: 21.8161%;">**`Math.sin(x)`**</td><td style="width: 39.3281%;">Retorna el sinus d'un angle <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span>. **Nota:** L'angle s'ha de passar en **radians**.</td><td style="width: 33.7306%;">`Math.sin(Math.PI / 2)`</td><td style="width: 5.12515%;">`1`</td></tr></tbody></table>

</div>## Mètodes d'Arrodoniment i Retallada

Aquests mètodes són essencials per controlar la precisió dels números de coma flotant.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-1"><table style="width: 100%;"><thead><tr><td style="width: 20.0138%;">Mètode</td><td style="width: 48.5202%;">Descripció</td><td style="width: 24.4338%;">Exemple</td><td style="width: 7.03218%;">Resultat</td></tr></thead><tbody><tr><td style="width: 20.0138%;">**`Math.round(x)`**</td><td style="width: 48.5202%;">Arrodoneix <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> a l'enter més proper. Si el decimal és exactament `.5`, arrodoneix cap a dalt.</td><td style="width: 24.4338%;">`Math.round(4.6)` / `Math.round(4.4)`</td><td style="width: 7.03218%;">`5` / `4`</td></tr><tr><td style="width: 20.0138%;">**`Math.ceil(x)`**</td><td style="width: 48.5202%;">**Sostre**. Arrodoneix <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> a l'enter immediatament **superior** (cap a +<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">∞</span></span></span></span></span>).</td><td style="width: 24.4338%;">`Math.ceil(4.1)` / `Math.ceil(-4.9)`</td><td style="width: 7.03218%;">`5` / `-4`</td></tr><tr><td style="width: 20.0138%;">**`Math.floor(x)`**</td><td style="width: 48.5202%;">**Sòl**. Arrodoneix <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord mathnormal">x</span></span></span></span></span> a l'enter immediatament **inferior** (cap a -<span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">∞</span></span></span></span></span>).</td><td style="width: 24.4338%;">`Math.floor(4.9)` / `Math.floor(-4.1)`</td><td style="width: 7.03218%;">`4` / `-5`</td></tr><tr><td style="width: 20.0138%;">**`Math.trunc(x)`**</td><td style="width: 48.5202%;">**Truncar**. Simplement elimina la part decimal, deixant només l'enter. No fa cap tipus d'arrodoniment.</td><td style="width: 24.4338%;">`Math.trunc(4.9)` / `Math.trunc(-4.1)`</td><td style="width: 7.03218%;">`4` / `-4`</td></tr></tbody></table>

</div>## Mètodes de Selecció i Aleatoris

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-2"><table style="width: 100%;"><thead><tr><td style="width: 26.3409%;">Mètode</td><td style="width: 39.4517%;">Descripció</td><td style="width: 21.8077%;">Exemple</td><td style="width: 12.2805%;">Resultat (Exemple)</td></tr></thead><tbody><tr><td style="width: 26.3409%;">**`Math.max(a, b, ...)`**</td><td style="width: 39.4517%;">Retorna el valor més gran d'una llista de nombres.</td><td style="width: 21.8077%;">`Math.max(10, 5, 20)`</td><td style="width: 12.2805%;">`20`</td></tr><tr><td style="width: 26.3409%;">**`Math.min(a, b, ...)`**</td><td style="width: 39.4517%;">Retorna el valor més petit d'una llista de nombres.</td><td style="width: 21.8077%;">`Math.min(10, 5, 20)`</td><td style="width: 12.2805%;">`5`</td></tr><tr><td style="width: 26.3409%;">**`Math.random()`**</td><td style="width: 39.4517%;">Retorna un número pseudo-aleatori entre <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">0</span></span></span></span></span> (inclòs) i <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mord">1</span></span></span></span></span> (exclòs).</td><td style="width: 21.8077%;">`Math.random()`</td><td style="width: 12.2805%;">`0.78912...`</td></tr></tbody></table>

</div>### Generació de Números Aleatoris en un Rang

`Math.random()` per si sol no és molt útil. Normalment s'utilitza amb `Math.floor()` per obtenir un enter dins d'un rang específic:

**Exemple: Generar un enter entre 1 i 10 (ambdós inclosos)**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-472 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_697fb360cc2fb931","c_cb55861d8f3a287e",null,"rc_9cc85b75bca04aa6",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-472 ng-star-inserted"><span class="ng-tns-c3729132635-472">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-472 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-472 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-472"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-472"></div></div></div>```javascript
// Math.random() * 10 dóna un valor entre 0 i 9.999...
// Math.floor(...) fa que sigui un enter entre 0 i 9.
// + 1 desplaça el rang a 1 i 10.
let numAleatori = Math.floor(Math.random() * 10) + 1; 

console.log(numAleatori); // Pot ser 1, 2, ..., fins a 10.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-472 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_697fb360cc2fb931","c_cb55861d8f3a287e",null,"rc_9cc85b75bca04aa6",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-472"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-472"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>

# Objecte Regexp

Les **Expressions Regulars (RegExp)** a JavaScript són una eina extremadament potent i sofisticada per processar text. Són objectes que us permeten definir **patrons de cerca complexos** per validar formats (com emails, dates, telèfons) i realitzar operacions de cerca i substitució en cadenes de text.

La sintaxi bàsica utilitza la **notació literal**: el patró s'embolcalla entre barres inclinades (`/`): `/patro/modificadors`.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div>## Modificadors (Flags)

Els modificadors es col·loquen al final de l'expressió i alteren la forma en què es realitza la cerca. El seu ús és crucial per a cerques efectives.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-modificador-nom-prop"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"><table><thead><tr><td>Modificador</td><td>Nom</td><td>Propòsit</td><td>Exemple</td></tr></thead><tbody><tr><td>**`i`**</td><td>*Case-Insensitive*</td><td>La cerca **ignora** si les lletres són majúscules o minúscules.</td><td>`/hola/i` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> coincideix amb "Hola" o "HOLA".</td></tr><tr><td>**`g`**</td><td>*Global*</td><td>Troba **totes** les coincidències a la cadena, en lloc de parar-se a la primera. Vital per a `match()` i `replaceAll()`.</td><td>`/a/g` <span class="math-inline"><span class="katex"><span aria-hidden="true" class="katex-html"><span class="base"><span class="mrel">→</span></span></span></span></span> troba totes les 'a'.</td></tr><tr><td>**`m`**</td><td>*Multiline*</td><td>Permet que `^` i `$` coincideixin amb l'inici i el final de **cada línia** dins d'una cadena multilínia, i no només amb l'inici i el final de tota la cadena.</td><td>N/A</td></tr></tbody></table>

</div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-539 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-539 ng-star-inserted"><span class="ng-tns-c3729132635-539">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-539 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-539 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-539"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-539"></div></div></div>```javascript
let text = "Pere, Anna i Pere.";
let patroSenseG = /Pere/;
let patroAmbG = /Pere/g;

console.log(text.match(patroSenseG)); // ['Pere'] (Només la primera)
console.log(text.match(patroAmbG));    // ['Pere', 'Pere'] (Totes les ocurrències)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-539 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-539"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-539"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div>## Mètodes d'Ús Bàsic

### 1. Validació Lògica: `RegExp.prototype.test()`

Aquest mètode, cridat sobre l'objecte RegExp, és la manera més ràpida de comprovar l'existència d'un patró.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-540 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-540 ng-star-inserted"><span class="ng-tns-c3729132635-540">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-540 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-540 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-540"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-540"></div></div></div>```javascript
var cad = "Curs de JavaScript de la Caparrella";
var patroSenseMayusc = /caparrella/i; 
var patroSensible = /CAPARRELLA/;

console.log(patroSenseMayusc.test(cad));  // true (gràcies al modificador 'i')
console.log(patroSensible.test(cad));     // true (la coincidència literal existeix)
console.log(/llapis/.test(cad));         // false
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-540 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-540"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-540"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div>### 2. Extreure Coincidències: `String.prototype.match()`

Aquest mètode, cridat sobre l'objecte `String`, retorna un array amb els resultats. Si no s'utilitza el modificador `g`, l'array conté detalls addicionals (índex, grup de captures). Si s'utilitza `g`, només conté les subcadenes coincidents.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-541 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-541 ng-star-inserted"><span class="ng-tns-c3729132635-541">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-541 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-541 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-541"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-541"></div></div></div>```javascript
var cad="Curs de JavaScript de la Caparrella";
var patro = /Caparrella/i;

var res = cad.match(patro);
console.log(res); 
/* Amb patró sense 'g', retorna un Array amb detalls:
[ 
  'Caparrella', 
  index: 25, 
  input: 'Curs de JavaScript de la Caparrella', 
  groups: undefined 
] 
*/
console.log(res[0]); // 'Caparrella'
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-541 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-541"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-541"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8"></div>## Metacaràcters i Quantificadors (Sintaxi del Patró)

Els símbols especials (metacaràcters) descriuen el patró amb lògica, no només amb literals.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-s%C3%ADmbol-nom-descripci"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"><table style="width: 100%;"><thead><tr><td style="width: 13.5876%;">Símbol</td><td style="width: 18.5936%;">Nom</td><td style="width: 30.5246%;">Descripció</td><td style="width: 17.3896%;">Exemple</td><td style="width: 19.9046%;">Coincideix amb...</td></tr></thead><tbody><tr><td style="width: 13.5876%;">**`^` / `$`**</td><td style="width: 18.5936%;">Inici / Final</td><td style="width: 30.5246%;">Garanteixen que la coincidència es produeixi a l'inici (`^`) o al final (`$`) de la cadena. **Crucial per a la validació de formats.**</td><td style="width: 17.3896%;">`^a$`</td><td style="width: 19.9046%;">Només la cadena "a".</td></tr><tr><td style="width: 13.5876%;">**`[abc]`**</td><td style="width: 18.5936%;">Conjunt</td><td style="width: 30.5246%;">Coincideix amb **un sol caràcter** que sigui 'a', 'b' o 'c'.</td><td style="width: 17.3896%;">`[aeiou]`</td><td style="width: 19.9046%;">Qualsevol vocal.</td></tr><tr><td style="width: 13.5876%;">**`[a-z]`**</td><td style="width: 18.5936%;">Rang</td><td style="width: 30.5246%;">Coincideix amb **un sol caràcter** dins del rang definit.</td><td style="width: 17.3896%;">`[0-9]{3}`</td><td style="width: 19.9046%;">Un número de tres dígits (p. ex. "123").</td></tr><tr><td style="width: 13.5876%;">**`?`**</td><td style="width: 18.5936%;">Zero o U</td><td style="width: 30.5246%;">Fa que el caràcter o grup precedent sigui **opcional**.</td><td style="width: 17.3896%;">`còdi(c)?`</td><td style="width: 19.9046%;">"còdi" o "còdic".</td></tr><tr><td style="width: 13.5876%;">**`+`**</td><td style="width: 18.5936%;">Un o Més</td><td style="width: 30.5246%;">L'element precedent ha d'aparèixer almenys una vegada.</td><td style="width: 17.3896%;">`a+`</td><td style="width: 19.9046%;">"a", "aa", "aaa", etc.</td></tr><tr><td style="width: 13.5876%;">**`{n,m}`**</td><td style="width: 18.5936%;">Repeticions</td><td style="width: 30.5246%;">L'element precedent es repeteix entre `n` (mínim) i `m` (màxim) vegades.</td><td style="width: 17.3896%;">`\d{2,4}`</td><td style="width: 19.9046%;">2, 3 o 4 dígits.</td></tr><tr><td style="width: 13.5876%;">**`\d` / `\s`**</td><td style="width: 18.5936%;">Abstracció</td><td style="width: 30.5246%;">Representen un dígit (`\d`) o un espai en blanc (`\s`).</td><td style="width: 17.3896%;">`\d-\d`</td><td style="width: 19.9046%;">Un dígit, un guió, un dígit (p.ex. "5-9").</td></tr></tbody></table>

</div></div>### Exemple 1: Validació de Format de Data (`dd/mm/aaaa`)

Aquesta expressió il·lustra l'ús de rangs, alternances (`|`) i quantificadors (`?`) per a una validació de format:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-542 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-542 ng-star-inserted"><span class="ng-tns-c3729132635-542">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-542 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-542 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-542"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-542"></div></div></div>```javascript
// Patró que assegura que la cadena COMPLETA sigui dd/mm/aaaa
regexp = /^(3[01]|[12][0-9]|0?[1-9])\/(1[0-2]|0?[1-9])\/([0-9]{2})?[0-9]{2}$/;

// 3[01]: 30 o 31.
// [12][0-9]: 10 a 29.
// 0?[1-9]: 1 a 9, amb el 0 opcional (01, 1, 09, 9).
// \/ : La barra inclinada literal (escapada amb \).
// ([0-9]{2})? : L'any, pot ser 4 dígits o 2 (el grup de 2 dígits és opcional).

console.log(regexp.test("01/01/2016")); // true
console.log(regexp.test("1/1/16"));     // true
console.log(regexp.test("2016/01/01")); // false (No comença amb el patró ^)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-542 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-542"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-542"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div>### Exemple 2: Validació de Targeta de Crèdit (Format)

Aquesta expressió utilitza la lògica d'alternança per acceptar dos tipus de separadors vàlids: el guió o l'espai.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--12"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr"></div></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-543 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-543 ng-star-inserted"><span class="ng-tns-c3729132635-543">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-543 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-543 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-543"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-543"></div></div></div>```javascript
// Valida 4 grups de 4 dígits, separats per un guió o un espai.
regexpTargeta = /^\d{4}(-|\s)\d{4}(-|\s)\d{4}(-|\s)\d{4}$/;

// \d{4} : Exactament quatre dígits.
// (-|\s) : Grup d'alternança: accepta un guió (-) O un espai en blanc (\s).

console.log(regexpTargeta.test("3782-8224-6310-0067")); // true
console.log(regexpTargeta.test("3782 8224 6310 0067")); // true
console.log(regexpTargeta.test("3782*8224*6310*0067")); // false (El * no és vàlid)
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-543 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--13" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_b3bf731aecddfed2","c_cb55861d8f3a287e",null,"rc_180401f909e4ce80",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-543"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-543"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--14"><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--15"></div></div>

# Objecte array

Els **Arrays** en JavaScript són objectes especials que s'utilitzen per emmagatzemar col·leccions ordenades de dades. A diferència de molts altres llenguatges, els *arrays* de JavaScript poden contenir dades de diferents tipus (números, strings, objectes, etc.) i tenen una mida dinàmica.

## L'Objecte `Array`

Els *arrays* tenen poques propietats, però la més important és la que defineix la seva mida.

### `length`

La propietat **`length`** retorna el nombre d'elements en un *array*.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Modificable</td></tr></thead><tbody><tr><td>**`length`**</td><td>Retorna el nombre d'elements (o l'índex més alt + 1).</td><td>✅</td></tr></tbody></table>

</div>#### Exemple

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-184 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-184 ng-star-inserted"><span class="ng-tns-c532567586-184">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-184 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-184 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-184"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-184"></div></div></div>```javascript
let fruites = ['poma', 'plàtan', 'kiwi'];

console.log(fruites.length); // Resultat: 3

// CAS D'ÚS: Truncar (escurçar) l'array
fruites.length = 2;
console.log(fruites); // Resultat: ['poma', 'plàtan']
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-184 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-184"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-184"></div></div></div>## Mètodes

Els mètodes es divideixen en categories segons la seva funcionalitat:

### Mutació (Modifiquen original)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 18.5811%;">Mètode</td><td style="width: 43.0399%;">Descripció</td><td style="width: 38.379%;">Exemple</td></tr></thead><tbody><tr><td style="width: 18.5811%;">**`push()`**</td><td style="width: 43.0399%;">Afegeix un o més elements al **final** de l'array.</td><td style="width: 38.379%;">`arr.push('nou');`</td></tr><tr><td style="width: 18.5811%;">**`pop()`**</td><td style="width: 43.0399%;">Elimina i retorna l'últim element de l'array.</td><td style="width: 38.379%;">`let ultim = arr.pop();`</td></tr><tr><td style="width: 18.5811%;">**`unshift()`**</td><td style="width: 43.0399%;">Afegeix un o més elements a l'**inici** de l'array.</td><td style="width: 38.379%;">`arr.unshift('inici');`</td></tr><tr><td style="width: 18.5811%;">**`shift()`**</td><td style="width: 43.0399%;">Elimina i retorna el primer element de l'array.</td><td style="width: 38.379%;">`let primer = arr.shift();`</td></tr><tr><td style="width: 18.5811%;">**`splice()`**</td><td style="width: 43.0399%;">Mètode versàtil: permet afegir, eliminar o substituir elements començant per un índex.</td><td style="width: 38.379%;">`arr.splice(2, 1, 'substitut');` (A l'índex 2, elimina 1 i afegeix 'substitut').</td></tr><tr><td style="width: 18.5811%;">**`sort()`**</td><td style="width: 43.0399%;">Ordena els elements de l'array alfabèticament per defecte. Requereix una funció de comparació per a números.</td><td style="width: 38.379%;">`arr.sort((a, b) => a - b);` (Per ordenar números).</td></tr><tr><td style="width: 18.5811%;">**`reverse()`**</td><td style="width: 43.0399%;">Inverteix l'ordre dels elements de l'array.</td><td style="width: 38.379%;">`arr.reverse();`</td></tr></tbody></table>

</div>#### Exemple de Mutació

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-185 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-185 ng-star-inserted"><span class="ng-tns-c532567586-185">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-185 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-185 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-185"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-185"></div></div></div>```javascript
let colors = ['blau', 'vermell', 'groc'];

colors.push('verd');     // colors és ara ['blau', 'vermell', 'groc', 'verd']
let eliminat = colors.shift(); // eliminat és 'blau', colors és ['vermell', 'groc', 'verd']

// Elimina 'groc' i afegeix 'taronja'
colors.splice(1, 1, 'taronja'); // colors és ara ['vermell', 'taronja', 'verd']
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-185 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-185"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-185"></div></div></div>### Accés i Iteració (No modifiquen original)

Aquests mètodes no canvien l'array original, sinó que retornen un valor nou o un nou array.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ex-1" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 22.0346%;">Mètode</td><td style="width: 37.0834%;">Descripció</td><td style="width: 40.7628%;">Exemple</td></tr></thead><tbody><tr><td style="width: 22.0346%;">**`concat()`**</td><td style="width: 37.0834%;">Combina dos o més arrays i retorna un **nou array**.</td><td style="width: 40.7628%;">`let nouArr = arr1.concat(arr2);`</td></tr><tr><td style="width: 22.0346%;">**`slice()`**</td><td style="width: 37.0834%;">Retorna una secció superficial (*shallow copy*) de l'array original en un **nou array**.</td><td style="width: 40.7628%;">`let copia = arr.slice(1, 3);` (Des de l'índex 1 fins al 3, sense incloure'l).</td></tr><tr><td style="width: 22.0346%;">**`join()`**</td><td style="width: 37.0834%;">Converteix tots els elements de l'array en una cadena (*string*), utilitzant el separador especificat.</td><td style="width: 40.7628%;">`let text = arr.join(' - ');`</td></tr><tr><td style="width: 22.0346%;">**`indexOf()`**</td><td style="width: 37.0834%;">Retorna el primer índex en què es pot trobar un element, o `-1` si no és present.</td><td style="width: 40.7628%;">`arr.indexOf('groc');`</td></tr><tr><td style="width: 22.0346%;">**`includes()`**</td><td style="width: 37.0834%;">Retorna un booleà (`true` o `false`) indicant si l'array conté un element concret.</td><td style="width: 40.7628%;">`arr.includes('verd');`</td></tr></tbody></table>

</div>#### Exemple d'Accés

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-186 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-186 ng-star-inserted"><span class="ng-tns-c532567586-186">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-186 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-186 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-186"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-186"></div></div></div>```javascript
let digits = [1, 2, 3, 4, 5];
let lletres = ['a', 'b'];

// Concat
let combinat = digits.concat(lletres); // [1, 2, 3, 4, 5, 'a', 'b']

// Slice
let part = digits.slice(2, 4); // [3, 4]

// Join
let csv = digits.join(','); // "1,2,3,4,5"
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-186 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-186"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-186"></div></div></div>### Iteració d'ordre superior (Looping i Transformació)

Aquests mètodes prenen una funció de *callback* com a argument i són fonamentals en la programació funcional moderna.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ca" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 18.5807%;">Mètode</td><td style="width: 46.7352%;">Descripció</td><td style="width: 34.6841%;">Cas d'Ús</td></tr></thead><tbody><tr><td style="width: 18.5807%;">**`forEach()`**</td><td style="width: 46.7352%;">Executa una funció *callback* una vegada per a cada element. No retorna res.</td><td style="width: 34.6841%;">Executar una acció (p. ex., imprimir) per a cada element.</td></tr><tr><td style="width: 18.5807%;">**`map()`**</td><td style="width: 46.7352%;">Crea un **nou array** amb els resultats de la crida a una funció per a cada element.</td><td style="width: 34.6841%;">Transformar tots els elements d'un array (p. ex., multiplicar per 2).</td></tr><tr><td style="width: 18.5807%;">**`filter()`**</td><td style="width: 46.7352%;">Crea un **nou array** amb tots els elements que superin la prova implementada per la funció de *callback* (que ha de retornar `true`).</td><td style="width: 34.6841%;">Seleccionar elements que compleixen una condició (p. ex., números parells).</td></tr><tr><td style="width: 18.5807%;">**`reduce()`**</td><td style="width: 46.7352%;">Aplica una funció a un acumulador i a cada element de l'array (d'esquerra a dreta) per reduir-lo a un únic valor.</td><td style="width: 34.6841%;">Sumar tots els elements o calcular un valor únic a partir de l'array.</td></tr><tr><td style="width: 18.5807%;">**`find()`**</td><td style="width: 46.7352%;">Retorna el **primer element** de l'array que satisfà la funció de prova.</td><td style="width: 34.6841%;">Trobar el primer objecte que té una propietat específica.</td></tr><tr><td style="width: 18.5807%;">**`some()`**</td><td style="width: 46.7352%;">Retorna `true` si **almenys un** element de l'array satisfà la funció de prova.</td><td style="width: 34.6841%;">Comprovar si hi ha algun producte en estoc.</td></tr><tr><td style="width: 18.5807%;">**`every()`**</td><td style="width: 46.7352%;">Retorna `true` si **tots** els elements de l'array satisfan la funció de prova.</td><td style="width: 34.6841%;">Comprovar si tots els usuaris són majors d'edat.</td></tr></tbody></table>

</div>#### Exemples d'Iteració

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-187 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-187 ng-star-inserted"><span class="ng-tns-c532567586-187">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-187 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-187 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-187"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-187"></div></div></div>```javascript
const preus = [10, 25, 5, 50];

// 🔸 map(): Crear un nou array amb impostos
const preusAmbIva = preus.map(preu => preu * 1.21);
console.log(preusAmbIva); // Resultat: [12.1, 30.25, 6.05, 60.5]

// 🔸 filter(): Seleccionar només els barats
const ofertes = preus.filter(preu => preu < 30);
console.log(ofertes); // Resultat: [10, 25, 5]

// 🔸 reduce(): Sumar tots els elements
const sumaTotal = preus.reduce((acumulador, valorActual) => acumulador + valorActual, 0);
console.log(sumaTotal); // Resultat: 90
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-187 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c6ddd23ec00f50e7","c_3942556f22833484",null,"rc_3af0f00185982bb0",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-187"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-187"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>

# Browser objects

Els Browser Object Model (BOM), o Objectes del Navegador, són jerarquies d'objectes proporcionades pel navegador web (no l'estàndard ECMAScript) que permeten a JavaScript interactuar i manipular la finestra del navegador i el seu entorn, anomenat entorn host.

**Objecte window: El Global**

L'objecte window és l'objecte global del BOM i representa la finestra o pestanya oberta del navegador. Tots els altres objectes del BOM, com location, history, screen, i navigator, són propietats o sub-objectes de window. Les variables i funcions globals de JavaScript esdevenen propietats de l'objecte window.

**Objectes Clau del BOM**

Els objectes principals i les seves funcionalitats són:

- **window**: La pròpia finestra del navegador. Propietats com window.innerWidth (amplada de la finestra) o mètodes com alert(), setTimeout(), i open()
- **location**: Proporciona informació detallada sobre la URL actual del document (protocol, host, path, etc.)
- **history**: Permet navegar cap enrere i endavant a través de l'historial de sessions de la pestanya. És fonamental per a les Single Page Applications (SPAs) el control del state
- **navigator**: Conté dades sobre el navegador de l'usuari i el sistema operatiu (SO), altres com la cadena d'identificació, l'estat de la connexió o accés a APIs del dispositiu com la geolocalització o la càmera/micròfon
- **screen**: Proporciona informació sobre la pantalla física de l'usuari, com la resolució total , la profunditat de color...

# Qué són els browser objects?

[![image.png](https://siensis.com/books/uploads/images/gallery/2025-09/scaled-1680-/EPAbWJ7NrBRDdxfG-image.png)](https://siensis.com/books/uploads/images/gallery/2025-09/EPAbWJ7NrBRDdxfG-image.png)

 Els **Browser Object Model (BOM)** són un conjunt d'objectes que el navegador crea per interactuar amb la finestra del navegador i la seva funcionalitat, a més del contingut del document (que es gestiona mitjançant el DOM, a través de l'objecte `document`).

### **`window` (L'Objecte Global)**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-%C3%A9s%3A-%C3%89s-l%27objecte">- **Què és:** És l'objecte **arrel (o global)** del BOM. Totes les variables i funcions globals de JavaScript esdevenen propietats i mètodes de l'objecte `window`. Representa la finestra oberta del navegador o el *frame* que conté el document.
- **Rol Principal:** Proporciona accés a les funcions del navegador i serveix de contenidor per a altres objectes del BOM, com `document`, `location`, `history`, etc. També gestiona **temporitzadors** (`setTimeout`, `setInterval`) i la creació de **subfinestres** (`pop-ups`).

</div>#### **Exemples:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-acci%C3%B3-codi-javascrip"><table style="width: 100%;"><thead><tr><td style="width: 13.7068%;">Acció</td><td style="width: 50.4105%;">Codi JavaScript</td><td style="width: 35.8827%;">Descripció</td></tr></thead><tbody><tr><td style="width: 13.7068%;">Alerta</td><td style="width: 50.4105%;">`window.alert('Hola món!');`</td><td style="width: 35.8827%;">Mostra una finestra d'alerta. (`window.` és sovint opcional).</td></tr><tr><td style="width: 13.7068%;">Temporitzador</td><td style="width: 50.4105%;">`setTimeout(function() { console.log('1s passat'); }, 1000);`</td><td style="width: 35.8827%;">Executa una funció després d'1 segon.</td></tr><tr><td style="width: 13.7068%;">Mida de la finestra</td><td style="width: 50.4105%;">`console.log(window.innerWidth);`</td><td style="width: 35.8827%;">Retorna l'amplada de l'àrea de visualització (viewport) en píxels.</td></tr></tbody></table>

 </div>### **`location` (La URL)**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-%C3%A9s%3A-cont%C3%A9-inform">- **Què és:** Conté informació detallada sobre la **URL (Uniform Resource Locator)** actual de la finestra (el document que s'està mostrant).
- **Rol Principal:** Permet **llegir** i **modificar** la direcció web, cosa que provoca que el navegador navegui a una nova pàgina o recarregui l'actual.

</div>#### **Exemples:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-acci%C3%B3-codi-javascrip-1"><table><thead><tr><td>Acció</td><td>Codi JavaScript</td><td>Descripció</td></tr></thead><tbody><tr><td>URL actual</td><td>`console.log(location.href);`</td><td>Mostra la URL completa (p. ex., `http://example.com/pagina.html`).</td></tr><tr><td>Redirecció</td><td>`location.href = 'https://google.com';`</td><td>Carrega la pàgina de Google.</td></tr><tr><td>Recàrrega</td><td>`location.reload();`</td><td>Recarrega la pàgina actual.</td></tr></tbody></table>

 </div>### **`history` (Historial de Navegació)**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-%C3%A9s%3A-cont%C3%A9-inform-1">- **Què és:** Conté informació sobre les **direccions URL** que l'usuari ha visitat en la **sessió actual** (la pestanya o finestra).
- **Rol Principal:** Permet al codi JavaScript **navegar cap enrere o endavant** en l'historial del navegador, simulant els botons 'Enrere' i 'Endavant'.

</div>#### **Exemples:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-acci%C3%B3-codi-javascrip-2"><table><thead><tr><td>Acció</td><td>Codi JavaScript</td><td>Descripció</td></tr></thead><tbody><tr><td>Enrere</td><td>`history.back();`</td><td>Equivalent a fer clic al botó 'Enrere' del navegador.</td></tr><tr><td>Endavant</td><td>`history.forward();`</td><td>Equivalent a fer clic al botó 'Endavant' del navegador.</td></tr><tr><td>Moure's</td><td>`history.go(-2);`</td><td>Torna **dues** pàgines enrere en l'historial.</td></tr></tbody></table>

</div>### **`document` (El DOM)**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-qu%C3%A8-%C3%A9s%3A-cont%C3%A9-tota-l">- **Què és:** Conté tota la **informació i l'estructura del contingut web** que es mostra actualment a la finestra (el fitxer HTML i els seus elements). És la porta d'entrada al **Document Object Model (DOM)**.
- **Rol Principal:** Permet accedir, manipular i interactuar amb tots els elements de la pàgina (etiquetes, textos, imatges, formularis, estils, etc.). També conté objectes per a dades globals com `cookies` o el `títol` de la pàgina.

</div>#### **Exemples:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-acci%C3%B3-codi-javascrip-3"><table><thead><tr><td>Acció</td><td>Codi JavaScript</td><td>Descripció</td></tr></thead><tbody><tr><td>Títol</td><td>`console.log(document.title);`</td><td>Retorna el text de l'etiqueta `<title>`.</td></tr><tr><td>Accés a element</td><td>`let boto = document.getElementById('btn');`</td><td>Obté un element HTML per la seva ID.</td></tr><tr><td>Canvi de fons</td><td>`document.body.style.backgroundColor = 'lightblue';`</td><td>Canvia el color de fons del cos de la pàgina.</td></tr></tbody></table>

 </div>### **Els Events (Interactivitat)**

És important subratllar que, a més de propietats (dades) i mètodes (funcions), tots aquests objectes són fonamentals per a la **interactivitat** a través dels **events**.

Un **event** és una acció que té lloc a la pàgina web, sovint provocada per l'usuari (p. ex., un clic, escriure, moure el ratolí, carregar la pàgina). Els objectes del BOM (especialment `window` i `document`) permeten **escoltar** i **respondre** a aquests esdeveniments.

#### **Exemple d'Event:**

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-23 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_e23f80fe658a0979","c_33541e2542bc1d79",null,"rc_90df1b96eb3cdc21",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-23 ng-star-inserted"><span class="ng-tns-c3729132635-23">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-23 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-23 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-23"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-23">  
</div></div></div>```
// L'event es dispara quan la pàgina (document)
// ha acabat de carregar tots els seus elements.
window.onload = function() {
    console.log("La pàgina s'ha carregat completament!");
};

// L'event es dispara quan l'usuari fa clic
// en un element (suposant que existeix un amb ID 'elMeuBoto')
document.getElementById('elMeuBoto').onclick = function() {
    alert("Has fet clic!");
};

```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-23 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_e23f80fe658a0979","c_33541e2542bc1d79",null,"rc_90df1b96eb3cdc21",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-23"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-23"></div></div></div>

# Objecte window

##  L'Objecte `window`: L'Arrel del Navegador

L'objecte **`window`** és l'objecte **global** de JavaScript quan s'executa en un navegador web. No només representa la finestra oberta del navegador, sinó que també és el contenidor per a **tots** els altres objectes del BOM (com `document`, `location`, `history`, etc.) i per a les variables i funcions globals de JavaScript.

### La Jerarquia (BOM i DOM)

La jerarquia del navegador i el document es construeix a partir de `window`:

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-window-%28bom%29%3A-l%27arre">1. **`window` (BOM):** L'arrel. Representa la finestra/pestanya sencera.
2. **`document` (DOM):** Fill de `window`. Representa el contingut HTML carregat dins d'aquesta finestra.
3. **Elements HTML:** Fills de `document`. Representen etiquetes concretes (com `<img>`, `<button>`, etc.).

</div>L'objecte `window` es pot **ometre** en la majoria de referències als seus fills (p. ex., `window.document` és el mateix que `document`, i `window.alert()` és `alert()`).

#### **Exemple de Jerarquia (DOM)**

L'accés directe a elements com `document.img1` (utilitzant l'atribut `name`) és un mètode antic i no es recomana actualment. El mètode estàndard per accedir a elements és utilitzar el **DOM (Document Object Model)**.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-antic-%28desaco"><table><thead><tr><td>Mètode Antic (Desaconsellat)</td><td>Mètode Modern (Recomanat)</td></tr></thead><tbody><tr><td>`console.log(document.img1.width);`</td><td>**`document.getElementById('id_de_la_imatge').width;`**</td></tr></tbody></table>

</div>**Codi HTML/JavaScript Modern:**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-36 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-html" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-36 ng-star-inserted"><span class="ng-tns-c3729132635-36">HTML</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-36 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-36 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-36"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-36">  
</div></div></div>```html

<html>
    <body>
        <img src="./muntanya.jpg" id="muntanyaImg" alt="Muntanya" />
        <script>
            // Accedim a l'objecte document a través de window
            const imatge = document.getElementById('muntanyaImg');
            
            // Accés a propietats de l'element <img>
            console.log("Amplada de la imatge:", imatge.width); 
            
            // Accés a una propietat de window (sense window.)
            console.log("URL de la pàgina:", location.href); 
        </script>
    </body>
</html>
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-36 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-36"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-36"></div></div></div>## Propietats Clau de l'Objecte `window`

Les propietats de `window` permeten obtenir informació sobre l'estat del navegador i del document.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3"><table style="width: 100%;"><thead><tr><td style="width: 19.1777%;">Propietat</td><td style="width: 48.1443%;">Descripció</td><td style="width: 32.7674%;">Exemple Pràctic</td></tr></thead><tbody><tr><td style="width: 19.1777%;">**`document`**, **`location`**, **`history`**</td><td style="width: 48.1443%;">Són els objectes fonamentals del BOM que ja coneixes.</td><td style="width: 32.7674%;">`console.log(document.title);`</td></tr><tr><td style="width: 19.1777%;">**`innerWidth`**, **`innerHeight`**</td><td style="width: 48.1443%;">Retornen l'**amplada** i **altura de l'àrea visible (viewport)** del navegador en píxels, excloent les barres d'eines, etc.</td><td style="width: 32.7674%;">`console.log(window.innerWidth);`</td></tr><tr><td style="width: 19.1777%;">**`screenX`**, **`screenY`**</td><td style="width: 48.1443%;">Retornen la **posició horitzontal i vertical** de la finestra del navegador respecte a la pantalla de l'usuari. (També `screenLeft`/`screenTop`).</td><td style="width: 32.7674%;">`console.log(window.screenX);`</td></tr><tr><td style="width: 19.1777%;">**`parent`**, **`top`**, **`self`**</td><td style="width: 48.1443%;">Utilitzades principalment per treballar amb **`iframes`** (marcs). `parent` és el pare immediat; `top` és la finestra superior (l'arrel de totes les subfinestres); `self` és la finestra actual (`window`).</td><td style="width: 32.7674%;">Permet trencar l'iframe: `if (window !== window.top) { window.top.location.href = location.href; }`</td></tr><tr><td style="width: 19.1777%;">**`localStorage`**, **`sessionStorage`**</td><td style="width: 48.1443%;">Ofereixen un mecanisme per **emmagatzemar dades** de forma permanent (`localStorage`) o durant la sessió actual (`sessionStorage`) al navegador de l'usuari.</td><td style="width: 32.7674%;">`localStorage.setItem('usuari', 'Jordi');`</td></tr><tr><td style="width: 19.1777%;">**`closed`**</td><td style="width: 48.1443%;">Retorna un valor booleà (`true`/`false`) indicant si la finestra ha estat tancada.</td><td style="width: 32.7674%;">`if (myWindow.closed) { ... }`</td></tr><tr><td style="width: 19.1777%;">`status`, `defaultStatus`</td><td style="width: 48.1443%;">(***Nota d'ús:*** Aquestes propietats estan àmpliament **obsoletes** o ignorades pels navegadors moderns per raons de seguretat i usabilitat).</td><td style="width: 32.7674%;"> </td></tr></tbody></table>

</div>**Exemple de Propietats (BOM):**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-37 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-37 ng-star-inserted"><span class="ng-tns-c3729132635-37">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-37 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-37 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-37"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-37">  
</div></div></div>```javascript
// La mida interior del viewport (la part de la web)
console.log(`Mida del viewport: ${window.innerWidth}x${window.innerHeight}`);

// La posició de la finestra a la pantalla
console.log(`Posició a la pantalla (X, Y): ${window.screenX}, ${window.screenY}`);

// Emmagatzemant una dada
window.localStorage.setItem('tema', 'fosc');
console.log(`Tema guardat: ${localStorage.getItem('tema')}`); 
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-37 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-37"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-37"></div></div></div>## Mètodes Fonamentals de l'Objecte `window`

Els mètodes de `window` s'utilitzen per gestionar la finestra del navegador i la interacció amb l'usuari.

### **Mètodes d'Interacció amb l'Usuari**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem"><table style="width: 100%;"><thead><tr><td style="width: 21.9218%;">Mètode</td><td style="width: 47.545%;">Propòsit</td><td style="width: 30.5034%;">Exemple Pràctic</td></tr></thead><tbody><tr><td style="width: 21.9218%;">**`alert(missatge)`**</td><td style="width: 47.545%;">Mostra un missatge a l'usuari i espera que faci clic a OK.</td><td style="width: 30.5034%;">`alert('Benvingut!');`</td></tr><tr><td style="width: 21.9218%;">**`confirm(missatge)`**</td><td style="width: 47.545%;">Mostra un missatge i botons OK/Cancel. **Retorna `true` o `false`**.</td><td style="width: 30.5034%;">`const volEsborrar = confirm('Estàs segur?');`</td></tr><tr><td style="width: 21.9218%;">**`prompt(missatge, [textDefecte])`**</td><td style="width: 47.545%;">Mostra un missatge i un camp de text per introduir dades. **Retorna la dada introduïda o `null`** si es cancel·la.</td><td style="width: 30.5034%;">`const nom = prompt('Introdueix el teu nom:', 'Anònim');`</td></tr></tbody></table>

</div>### **Mètodes de Finestra i Temporització**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem-1"><table style="width: 100%;"><thead><tr><td style="width: 26.2102%;">Mètode</td><td style="width: 40.6352%;">Propòsit</td><td style="width: 33.1248%;">Exemple Pràctic</td></tr></thead><tbody><tr><td style="width: 26.2102%;">**`open(url, name, params)`**</td><td style="width: 40.6352%;">**Crea una nova finestra** (o pestanya) amb una URL i paràmetres de mida i aparença. Retorna una referència a la nova finestra.</td><td style="width: 33.1248%;">`const popup = window.open('/avís.html', 'avís', 'width=400,height=200');`</td></tr><tr><td style="width: 26.2102%;">**`close()`**</td><td style="width: 40.6352%;">**Tanca la finestra** actual o una finestra creada per l'`open()`.</td><td style="width: 33.1248%;">`popup.close();`</td></tr><tr><td style="width: 26.2102%;">**`setTimeout(funció, msec)`**</td><td style="width: 40.6352%;">Executa la `funció` **una sola vegada** després que passin els mil·lisegons (`msec`).</td><td style="width: 33.1248%;">`const idTimer = setTimeout(() => { alert('Temps esgotat!'); }, 5000);`</td></tr><tr><td style="width: 26.2102%;">**`setInterval(funció, msec)`**</td><td style="width: 40.6352%;">Executa la `funció` **repetidament** cada `msec` mil·lisegons.</td><td style="width: 33.1248%;">`const idInterval = setInterval(() => { console.log('Tick'); }, 1000);`</td></tr><tr><td style="width: 26.2102%;">**`clearTimeout(id)`** / **`clearInterval(id)`**</td><td style="width: 40.6352%;">**Cancela** l'execució pendent de `setTimeout` o `setInterval`, utilitzant la ID que retornen.</td><td style="width: 33.1248%;">`clearTimeout(idTimer);`</td></tr></tbody></table>

</div>**Exemple de Mètodes (Temporització):**

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-38 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-38 ng-star-inserted"><span class="ng-tns-c3729132635-38">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-38 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-38 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-38"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-38">  
</div></div></div>```javascript
let comptador = 0;

// Configurar una funció que s'executa cada segon
const intervalId = setInterval(() => {
    comptador++;
    console.log(`Segons passats: ${comptador}`);
    
    // Aturar l'interval després de 5 segons
    if (comptador >= 5) {
        clearInterval(intervalId); // Atura el temporitzador
        console.log("Interval aturat.");
    }
}, 1000); 

// Una funció que s'executa només una vegada després de 100 mil·lisegons
setTimeout(() => {
    alert("Benvingut a la pàgina (amb setTimeout)");
}, 100);
```

## `window.open`

El mètode **`window.open()`** és una funció de JavaScript que s'utilitza per **obrir una nova finestra o una nova pestanya** al navegador. Et permet especificar la URL a carregar, el nom de la finestra i una sèrie de característiques de visualització, com les dimensions i les barres d'eines.

### Sintaxi i Paràmetres

La sintaxi completa de `window.open()` és:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-158 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-158 ng-star-inserted"><span class="ng-tns-c532567586-158">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-158 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-158 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-158"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-158"></div></div></div>```javascript
let novaFinestra = window.open(url, nomFinestra, especificacions, reemplaçarEntradaHistorial);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-158 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-158"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-158"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--7" inline-copy-host=""></div>#### `url` (String)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-descripci%C3%B3%3A-l%27url-de" inline-copy-host="">- **Descripció:** L'URL del document a carregar a la nova finestra.
- **Opcionalitat:** Opcional. Si s'omet (o és una cadena buida `""`), la nova finestra o pestanya es crea amb una pàgina en blanc (`about:blank`).
- **Exemple:** `'https://www.exemple.cat/pagina.html'`

</div>#### `nomFinestra` (String)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-descripci%C3%B3%3A-un-nom-p" inline-copy-host="">- **Descripció:** Un nom per a la nova finestra o pestanya.
- **Opcionalitat:** Opcional.
- **Casos d'Ús:**
    
    
    - Si el nom coincideix amb una finestra ja oberta, el contingut es **recarrega** en aquesta finestra existent en lloc d'obrir-ne una de nova.
    - Pots utilitzar valors especials com **`_blank`** (sempre obre una nova finestra o pestanya, per defecte) o **`_self`** (carrega l'URL a la finestra actual, actuant com una navegació normal).
- **Exemple:** `'popupLogin'`

</div>#### `especificacions` (String)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-descripci%C3%B3%3A-una-cade" inline-copy-host="">- **Descripció:** Una cadena separada per comes que defineix les dimensions i característiques visuals de la nova finestra. **Aquest paràmetre només té efecte real si el navegador obre una *finestra* nova**, no una pestanya.
- **Opcionalitat:** Opcional.
- **Exemples Comuns de Característiques:**
    
    
    - `width=W`: Amplada de la finestra en píxels.
    - `height=H`: Alçada de la finestra en píxels.
    - `left=X`, `top=Y`: Posició de la finestra a la pantalla.
    - `resizable=yes/no`: Si l'usuari pot redimensionar la finestra (sovint ignorat).
    - `toolbar=yes/no`: Mostra o amaga la barra d'eines del navegador (sovint ignorat).
- **Exemple:** `'width=600,height=400,left=100,top=100,resizable=no'`

</div>#### `reemplaçarEntradaHistorial` (Boolean)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-descripci%C3%B3%3A-indica-s" inline-copy-host="">- **Descripció:** Indica si l'URL que s'està obrint ha de reemplaçar l'entrada actual a l'historial de la nova finestra.
- **Opcionalitat:** Opcional (valor per defecte: `false`).
- **Cas d'Ús:** S'utilitza rarament. Si es posa a `true`, la funció funciona de manera similar a `location.replace()` dins de la nova finestra.

</div>### Valor de retorn

El mètode `window.open()` retorna una **referència a la nova finestra (objecte `window`)**.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-si-l%27obertura-t%C3%A9-%C3%A8xi" inline-copy-host="">- Si l'obertura té èxit, la variable `novaFinestra` contindrà l'objecte de la finestra emergent, permetent-te interactuar amb ella des del script original (p. ex., cridar funcions o tancar-la).
- Si l'obertura és bloquejada per un *pop-up blocker*, retorna **`null`**.

</div>### Restriccions importants (bloquejadors de Pop-ups)

La majoria dels navegadors tenen estrictes **polítiques de bloqueig de *pop-ups*** per millorar l'experiència d'usuari:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-activaci%C3%B3-per-usuari" inline-copy-host="">1. **Activació per Usuari:** Perquè `window.open()` funcioni correctament i no sigui bloquejat, ha de ser cridat **directament dins d'una funció que es desencadena per una interacció de l'usuari** (p. ex., un `click` d'un botó o una pulsació de tecla).
2. **Temps d'Espera:** Si intentes cridar `window.open()` després d'un `setTimeout` o d'una promesa asíncrona, serà molt probablement bloquejat.

</div>### Exemples i casos d'ús

#### Obrir una nova pestanya

Aquesta és la forma més comuna d'usar `window.open()` avui dia, ja que la majoria de navegadors ignoren les especificacions i obren una pestanya.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-159 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-159 ng-star-inserted"><span class="ng-tns-c532567586-159">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-159 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-159 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-159"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-159"></div></div></div>```javascript
document.getElementById('obrirPestanya').addEventListener('click', () => {
    // La majoria de navegadors ignoren el 'pop-up' i obren una pestanya
    window.open('https://www.google.com', '_blank'); 
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-159 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--9" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-159"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-159"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--10" inline-copy-host=""></div>#### Obrir una finestra centrada amb dimensions específiques

En alguns navegadors i configuracions, això pot obrir una finestra petita sense barra de navegació, ideal per a diàlegs o logotypes.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-160 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-160 ng-star-inserted"><span class="ng-tns-c532567586-160">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-160 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-160 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-160"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-160"></div></div></div>```javascript
function obrirLogin() {
    const ample = 400;
    const altura = 500;
    const esquerra = (screen.width / 2) - (ample / 2);
    const superior = (screen.height / 2) - (altura / 2);
    
    const especificacions = `width=${ample},height=${altura},left=${esquerra},top=${superior},resizable=no,toolbar=no,menubar=no`;

    // Intentem obrir la finestra de login, donant-li el nom 'loginWin'
    const loginWindow = window.open('login.html', 'loginWin', especificacions);

    if (loginWindow === null) {
        alert("El bloquejador de pop-ups ha impedit obrir la finestra de login.");
    }
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-160 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-160"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-160"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--13" inline-copy-host=""></div>#### Comunicació entre finestres

Utilitzant la referència retornada (`novaFinestra`), el script original pot interactuar amb el contingut de la nova finestra (si ambdues estan al mateix **origen**).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--14" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-161 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-161 ng-star-inserted"><span class="ng-tns-c532567586-161">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-161 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-161 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-161"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-161"></div></div></div>```javascript
let popup;

document.getElementById('obrir').addEventListener('click', () => {
    popup = window.open('salutacio.html', 'salutacio', 'width=300,height=200');
});

document.getElementById('enviarMissatge').addEventListener('click', () => {
    if (popup && !popup.closed) {
        // Crida una funció definida dins de salutacio.html (si tenen el mateix origen)
        popup.mostrarMissatge('Hola des de la finestra principal!');
    }
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-161 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--15" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_10440e533d4d442a","c_3942556f22833484",null,"rc_548589e358664962",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-161"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-161"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--16" inline-copy-host=""></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-38 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--18" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_23f86b8502c108d1","c_33541e2542bc1d79",null,"rc_c6032fd35e5e035b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-38"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-38"></div></div></div><div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--19"></div></body></html>

# Objecte document

## L'Objecte `document`: La Porta al DOM

L'objecte **`document`** és la propietat més important de l'objecte `window`. La seva funció principal és servir com a **node arrel** de l'estructura **DOM (Document Object Model)**, permetent al codi JavaScript accedir, inspeccionar i manipular el contingut, l'estructura i els estils del document HTML que es mostra.

Es pot visualitzar com l'arbre de nodes que representa el document HTML, on cada etiqueta, text o atribut és un node.

### Propietats Clau de l'Objecte `document`

Aquestes propietats permeten obtenir informació general sobre el document.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3"><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Exemple Pràctic</td></tr></thead><tbody><tr><td>**`title`**</td><td>Cadena de text que conté el contingut de l'etiqueta `<title>`. És **editable**.</td><td>`document.title = "Nou Títol 🏷️";`</td></tr><tr><td>**`location`**</td><td>Un objecte que conté la **URL completa** del document. (És idèntic a `window.location`).</td><td>`console.log(document.location.href);`</td></tr><tr><td>**`lastModified`**</td><td>Una cadena de text que indica la data i hora de l'última modificació del document.</td><td>`console.log(document.lastModified);`</td></tr><tr><td>**`cookie`**</td><td>Permet llegir i escriure les **galetes (cookies)** associades al document.</td><td>`document.cookie = "tema=fosc; expires=Fri, 31 Dec 2024 12:00:00 UTC";`</td></tr><tr><td>**`body`**</td><td>Retorna l'element `<body>` del document. Molt útil per canvis d'estil o afegir elements.</td><td>`document.body.style.backgroundColor = 'lightgray';`</td></tr><tr><td>**`documentElement`**</td><td>Retorna el node arrel del DOM, que normalment és l'element `<html>`.</td><td>`console.log(document.documentElement.tagName); // "HTML"`</td></tr></tbody></table>

  
</div>### Mètodes Clau per a la Manipulació del DOM 

Si bé `document.write()` existeix, els mètodes següents són la base de la manipulació moderna del DOM, ja que permeten la interacció amb elements específics sense sobreescriure tot el contingut.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-prop%C3%B2sit-exem"><table style="width: 100%;"><thead><tr><td style="width: 27.2821%;">Mètode</td><td style="width: 40.874%;">Propòsit</td><td style="width: 31.8141%;">Exemple Pràctic</td></tr></thead><tbody><tr><td style="width: 27.2821%;">**`getElementById(id)`**</td><td style="width: 40.874%;">**El més comú.** Retorna el primer element l'atribut `id` del qual coincideix amb el valor especificat.</td><td style="width: 31.8141%;">`const btn = document.getElementById('boto_enviar');`</td></tr><tr><td style="width: 27.2821%;">**`querySelector(selector)`**</td><td style="width: 40.874%;">Retorna el **primer element** que coincideixi amb un **selector CSS** (p. ex., `.classe`, `#id`, `p > a`).</td><td style="width: 31.8141%;">`const primerEnllac = document.querySelector('.menu a');`</td></tr><tr><td style="width: 27.2821%;">**`querySelectorAll(selector)`**</td><td style="width: 40.874%;">Retorna una **NodeList** (una llista) de tots els elements que coincideixen amb el selector CSS.</td><td style="width: 31.8141%;">`const totsElsParagrafs = document.querySelectorAll('p');`</td></tr><tr><td style="width: 27.2821%;">**`createElement(nomEtiqueta)`**</td><td style="width: 40.874%;">**Crea un nou node d'element** amb el nom d'etiqueta especificat (p. ex., 'div', 'p').</td><td style="width: 31.8141%;">`const nouDiv = document.createElement('div');`</td></tr><tr><td style="width: 27.2821%;">**`createTextNode(text)`**</td><td style="width: 40.874%;">Crea un nou **node de text**.</td><td style="width: 31.8141%;">`const textNode = document.createTextNode('Hola!');`</td></tr><tr><td style="width: 27.2821%;">**`appendChild(node)`**</td><td style="width: 40.874%;">Afegeix un node com a **últim fill** de l'element. (Aquest mètode és en realitat de l'element, no del document).</td><td style="width: 31.8141%;">`document.body.appendChild(nouDiv);`</td></tr></tbody></table>

</div>#### **Exemple de Manipulació del DOM**

Aquest exemple mostra com canviar el text d'un element i afegir un nou element a la pàgina.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-51 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-html" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_92bacce12aeca662","c_33541e2542bc1d79",null,"rc_0ea30144ca84f91f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-51 ng-star-inserted"><span class="ng-tns-c3729132635-51">HTML</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-51 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-51 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-51"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-51"></div></div></div>```html

<html>
<body>
    <h1 id="titol-principal">Benvingut</h1>
    <ul id="llista-tasques">
        <li>Tasca 1</li>
    </ul>

    <script>
        // 1. Canviar el contingut d'un element existent
        const titol = document.getElementById('titol-principal');
        titol.textContent = "Manipulació del DOM OK ✅"; // textContent és millor que innerHTML per text simple

        // 2. Crear i afegir un nou element
        const llista = document.getElementById('llista-tasques');
        
        // Crear un nou <li>
        const novaTasca = document.createElement('li'); 
        
        // Crear el text per a aquest <li>
        novaTasca.textContent = "Nova tasca dinàmica"; 
        
        // Afegir el nou <li> a la llista <ul>
        llista.appendChild(novaTasca); 
    </script>
</body>
</html>
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-51 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_92bacce12aeca662","c_33541e2542bc1d79",null,"rc_0ea30144ca84f91f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-51"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-51"></div></div></div>### Mètodes d'Escriptura (`write` / `open` / `close`)

Els mètodes **`write()`**, **`writeln()`**, **`open()`** i **`close()`** s'utilitzaven històricament per generar contingut de manera dinàmica.

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-advert%C3%A8ncia%3A-l%27%C3%BAs-de">- **Advertència:** L'ús de `document.write()` *després* que el document s'hagi carregat completament pot **sobreescriure tot el contingut de la pàgina**, ja que implícitament crida a `document.open()`. El seu ús modern és gairebé exclusivament dins de la fase de càrrega o dins d'una finestra creada per `window.open()`.

</div>#### **Exemple d'ús de `write()`** 

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2"></div><div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-52 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_92bacce12aeca662","c_33541e2542bc1d79",null,"rc_0ea30144ca84f91f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="code-block-decoration header-formatted gds-title-s ng-tns-c3729132635-52 ng-star-inserted"><span class="ng-tns-c3729132635-52">JavaScript</span><div _ngcontent-ng-c3729132635="" class="buttons ng-tns-c3729132635-52 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c3729132635-52 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-52"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-52"></div></div></div>```javascript
function reemplacarContingut() {
  // Obre el document per a escriptura, esborrant tot l'anterior
  document.open("text/html"); 
  
  document.write("<h2>Nou contingut generat dinàmicament</h2>");
  document.write("<p>La data d'avui és: " + new Date().toLocaleDateString() + "</p>");
  
  // Tanca el document i mostra el contingut (obligatori després de open)
  document.close(); 
}

// Si cridem aquesta funció, l'HTML original desapareixerà.
// Per això, la manipulació amb createElement és l'opció preferida.
```

<div _ngcontent-ng-c3729132635="" class="code-block ng-tns-c3729132635-52 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_92bacce12aeca662","c_33541e2542bc1d79",null,"rc_0ea30144ca84f91f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c3729132635="" class="formatted-code-block-internal-container ng-tns-c3729132635-52"><div _ngcontent-ng-c3729132635="" class="animated-opacity ng-tns-c3729132635-52"></div></div></div><p class="callout danger">**Atenció**. Mètode no recomanat</p>

<div _ngcontent-ng-c1476568811="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4"></div></body></html>

# Objecte location

L'objecte **`location`** de JavaScript és una propietat del objecte **`window`** (o del objecte **`document`**) i representa la **ubicació actual (URL) del document** que s'està mostrant al navegador. Permet llegir i modificar les diferents parts de l'URL i, per tant, navegar a altres pàgines o recarregar la pàgina actual.

Pots accedir-hi mitjançant `window.location` o simplement `location` (ja que `window` és l'objecte global).

## Propietats de `location`

L'objecte `location` ofereix diverses propietats de només lectura o lectura/escriptura que permeten accedir a les parts individuals de l'URL. Si modifiques una d'aquestes propietats (excepte `hash`, `search`, i `pathname` en certs contextos), el navegador intentarà navegar a la nova URL.

Suposem que l'URL actual és: `https://usuari:contrasenya@www.exemple.cat:8080/caminet/fitxer.html?id=123&nom=prova#seccio1`

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 11.0792%;">Propietat</td><td style="width: 40.5298%;">Descripció</td><td style="width: 36.8296%;">Exemple de Valor</td><td style="width: 11.5614%;">Modificable</td></tr></thead><tbody><tr><td style="width: 11.0792%;">**`href`**</td><td style="width: 40.5298%;">Tota l'URL completa.</td><td style="width: 36.8296%;">`https://usuari:contrasenya@www.exemple.cat:8080/caminet/fitxer.html?id=123&nom=prova#seccio1`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`protocol`**</td><td style="width: 40.5298%;">El protocol de l'URL, inclòs el caràcter `:`.</td><td style="width: 36.8296%;">`https:`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`host`**</td><td style="width: 40.5298%;">El nom del *host* (servidor) i el número de port (si no és el port per defecte).</td><td style="width: 36.8296%;">`www.exemple.cat:8080`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`hostname`**</td><td style="width: 40.5298%;">El nom del *host* (servidor), sense el port.</td><td style="width: 36.8296%;">`www.exemple.cat`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`port`**</td><td style="width: 40.5298%;">El número de port de l'URL. Si no s'especifica, és una cadena buida o el port per defecte (80 per HTTP, 443 per HTTPS).</td><td style="width: 36.8296%;">`8080`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`pathname`**</td><td style="width: 40.5298%;">El camí (path) de l'URL, que comença amb `/`.</td><td style="width: 36.8296%;">`/caminet/fitxer.html`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`search`**</td><td style="width: 40.5298%;">La cadena de consulta (query string), que comença amb `?`.</td><td style="width: 36.8296%;">`?id=123&nom=prova`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`hash`**</td><td style="width: 40.5298%;">El fragment o anclatge de l'URL, que comença amb `#`.</td><td style="width: 36.8296%;">`#seccio1`</td><td class="align-center" style="width: 11.5614%;">✅</td></tr><tr><td style="width: 11.0792%;">**`origin`**</td><td style="width: 40.5298%;">L'origen de l'URL (protocol, host, i port). De només lectura.</td><td style="width: 36.8296%;">`https://www.exemple.cat:8080`</td><td class="align-center" style="width: 11.5614%;">❌</td></tr></tbody></table>

</div>## Mètodes de `location`

L'objecte `location` té tres mètodes principals que s'utilitzen per a la navegació i la recàrrega de la pàgina.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ef" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 20.6147%;">Mètode</td><td style="width: 18.3603%;">Descripció</td><td style="width: 61.025%;">Efecte</td></tr></thead><tbody><tr><td style="width: 20.6147%;">**`assign(url)`**</td><td style="width: 18.3603%;">Carrega el recurs a l'URL especificat.</td><td style="width: 61.025%;">Afegeix una nova entrada a l'historial de navegació, permetent a l'usuari tornar enrere. És equivalent a assignar un valor a `location.href`.</td></tr><tr><td style="width: 20.6147%;">**`replace(url)`**</td><td style="width: 18.3603%;">Carrega el recurs a l'URL especificat.</td><td style="width: 61.025%;">Substitueix l'URL actual a l'historial de navegació, **evitant** que l'usuari pugui fer servir el botó "Enrere" per tornar a la pàgina anterior.</td></tr><tr><td style="width: 20.6147%;">**`reload(forceReload)`**</td><td style="width: 18.3603%;">Recarrega el document actual.</td><td style="width: 61.025%;">Recarrega la pàgina des del cau del navegador (per defecte). Si es passa `true` com a argument (`location.reload(true)`), força la recàrrega del servidor, ignorant la memòria cau.</td></tr></tbody></table>

</div>## Exemples, casos d'ús

### 1. Lectura de l'URL (Obtenir Informació)

Pots utilitzar les propietats per analitzar l'URL actual i extreure'n dades.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-32 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-32 ng-star-inserted"><span class="ng-tns-c532567586-32">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-32 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-32 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-32"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-32"></div></div></div>```javascript
// Si l'URL és: https://localhost:3000/productes/detall.html?sku=P45#reviews

console.log(location.protocol);  // Resultat: "https:"
console.log(location.hostname);  // Resultat: "localhost"
console.log(location.port);      // Resultat: "3000"
console.log(location.pathname);  // Resultat: "/productes/detall.html"
console.log(location.search);    // Resultat: "?sku=P45"
console.log(location.hash);      // Resultat: "#reviews"

// Cas d'ús: Obtenir un paràmetre de consulta (cal una petita lògica addicional o usar URLSearchParams)
const urlParams = new URLSearchParams(location.search);
const sku = urlParams.get('sku');
console.log(sku); // Resultat: "P45"
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-32 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-32"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-32"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### 2. Navegació i Redirecció

#### Redirecció standard (`assign` o `href`)

Afegeix l'URL a l'historial. L'usuari pot tornar a la pàgina anterior.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-33 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-33 ng-star-inserted"><span class="ng-tns-c532567586-33">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-33 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-33 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-33"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-33"></div></div></div>```javascript
// Mètode 1: Assignar a href
location.href = 'https://www.novaweb.cat/inici';

// Mètode 2: Usar el mètode assign() (equivalent)
location.assign('https://www.novaweb.cat/inici');

// Cas d'ús: Redireccionar l'usuari després d'una acció (ex: login)
if (usuariHaFetLogin) {
    location.href = '/dashboard';
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-33 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-33"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-33"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>#### Redirecció sense historial (`replace`)

S'utilitza per evitar que l'usuari torni a la pàgina anterior, per exemple, després d'un formulari de login o una pàgina de càrrega temporal.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-34 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-34 ng-star-inserted"><span class="ng-tns-c532567586-34">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-34 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-34 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-34"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-34"></div></div></div>```javascript
// La pàgina actual (ex: login.html) serà reemplaçada a l'historial pel dashboard.
location.replace('/dashboard'); 

// Cas d'ús: Evitar que l'usuari torni a la pàgina de login després d'entrar.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-34 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-34"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-34"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### 3. Recàrrega de pàgina (`reload`)

Per refrescar la pàgina actual.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-35 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-35 ng-star-inserted"><span class="ng-tns-c532567586-35">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-35 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-35 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-35"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-35"></div></div></div>```javascript
// Recàrrega normal (pot usar el cau del navegador)
location.reload(); 

// Recàrrega forçada (ignora el cau, forçant una nova petició al servidor)
location.reload(true);

// Cas d'ús: Actualitzar una llista de dades després d'esborrar un element.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-35 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-35"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-35"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div>### 4. Modificació de part de l'URL

Pots canviar components individuals per recarregar la pàgina a la mateixa base, però amb un nou valor.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--12" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-36 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-36 ng-star-inserted"><span class="ng-tns-c532567586-36">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-36 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-36 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-36"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-36"></div></div></div>```javascript
// Canviar el hash per anar a una altra secció de la mateixa pàgina
location.hash = 'contacte'; 
// L'URL canvia i el navegador es desplaça al nou anclatge, sense recarregar.

// Canviar la cadena de consulta per filtrar contingut
location.search = '?filtre=actiu&ordre=asc'; 
// El navegador recarregarà la pàgina amb la nova query string.

// Canviar el camí (pathname)
location.pathname = '/nous-productes'; 
// El navegador recarregarà la pàgina amb el nou camí.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-36 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--13" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_f8c545c3e7714c68","c_3942556f22833484",null,"rc_8c9e9640415e3910",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-36"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-36"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--14" inline-copy-host=""></div>

# Objecte history

L'objecte **`history`** de JavaScript és l'altre component clau per gestionar la navegació i l'experiència de l'usuari dins d'una aplicació web. `History` forma part del **BOM (Browser Object Model)** i proporciona accés a les sessions de l'historial del navegador, permetent-te navegar cap endavant i cap enrere dins de les pàgines visitades per l'usuari a la pestanya actual.

Es pot accedir-hi mitjançant `window.history` o simplement `history`.

## Propietats de `history`

L'objecte `history` té dues propietats principals, ambdues de només lectura.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 14.0644%;">Propietat</td><td style="width: 54.4784%;">Descripció</td><td style="width: 31.4572%;">Exemple de Valor</td></tr></thead><tbody><tr><td style="width: 14.0644%;">**`length`**</td><td style="width: 54.4784%;">Retorna el nombre d'entrades a l'historial de sessions del navegador per a la pestanya actual (incloent-hi la pàgina actual).</td><td style="width: 31.4572%;">`3` (Si l'usuari ha visitat dues pàgines abans de l'actual).</td></tr><tr><td style="width: 14.0644%;">**`state`**</td><td style="width: 54.4784%;">Retorna l'estat que es va passar a l'última entrada de l'historial mitjançant els mètodes `pushState()` o `replaceState()`. L'estat pot ser qualsevol valor o objecte serialitzable.</td><td style="width: 31.4572%;">`{ filtre: 'actiu', pagina: 2 }`</td></tr></tbody></table>

</div>## Mètodes de `history`

Els mètodes de `history` es divideixen en dues categories: navegació tradicional i manipulació de l'historial (clau per a les **Single Page Applications - SPAs**).

### Mètodes de Navegació

Aquests mètodes simulen la pulsació dels botons "Enrere" i "Endavant" del navegador.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ca" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 15.2563%;">Mètode</td><td style="width: 30.3886%;">Descripció</td><td style="width: 54.3551%;">Cas d'Ús</td></tr></thead><tbody><tr><td style="width: 15.2563%;">**`back()`**</td><td style="width: 30.3886%;">Simula el botó "Enrere". Carrega l'URL anterior a l'historial.</td><td style="width: 54.3551%;">Crear un botó de "Tornar" personalitzat dins de la pàgina.</td></tr><tr><td style="width: 15.2563%;">**`forward()`**</td><td style="width: 30.3886%;">Simula el botó "Endavant". Carrega l'URL següent a l'historial.</td><td style="width: 54.3551%;">Utilitzat menys freqüentment, però permet avançar a la pàgina posterior.</td></tr><tr><td style="width: 15.2563%;">**`go(delta)`**</td><td style="width: 30.3886%;">Carrega una pàgina específica a l'historial, on `delta` és un nombre.</td><td style="width: 54.3551%;">`history.go(0)`: Recarrega la pàgina actual (similar a `location.reload()`). `history.go(-2)`: Torna dues pàgines enrere.</td></tr></tbody></table>

</div>### Mètodes de manipulació historial (HTML5 History API)

Aquests són els mètodes més potents i s'utilitzen per canviar l'URL (i, per tant, l'estat) **sense recarregar la pàgina**, cosa essencial per a les SPAs.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-co" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 36.3528%;">Mètode</td><td style="width: 25.9869%;">Descripció</td><td style="width: 37.6603%;">Conseqüència</td></tr></thead><tbody><tr><td style="width: 36.3528%;">**`pushState(state, title, url)`**</td><td style="width: 25.9869%;">Afegeix una nova entrada a l'historial.</td><td style="width: 37.6603%;">Afegeix una nova entrada a l'historial **i canvia l'URL** a la barra d'adreces **sense recarregar** la pàgina. Permet l'ús dels botons d'historial.</td></tr><tr><td style="width: 36.3528%;">**`replaceState(state, title, url)`**</td><td style="width: 25.9869%;">Modifica l'entrada actual de l'historial.</td><td style="width: 37.6603%;">**Canvia l'URL** actual i el seu estat **sense recarregar** la pàgina. No afegeix una nova entrada a l'historial, sinó que sobreescriu la que hi ha.</td></tr></tbody></table>

</div>**Paràmetres per a `pushState` i `replaceState`:**

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-state-%28objecte%29%3A-un-" inline-copy-host="">1. **`state` (objecte):** Un objecte de dades que conté l'estat de la sessió. Quan l'usuari navega a aquesta entrada de l'historial (usant Enrere/Endavant), l'objecte `state` és restaurat i accessible mitjançant `history.state` o l'esdeveniment `popstate`.
2. **`title` (string):** Actualment ignorat per la majoria de navegadors, però es pot passar una cadena buida (`''`) o el títol de la nova pàgina.
3. **`url` (string):** La nova URL de la pàgina. Opcionalment, pot ser només el camí (`/productes/45`) sense l'origen.

</div>## Exemples i casos d'ús

### 1. Navegació Bàsica

Simplement movent-se per l'historial.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-55 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-55 ng-star-inserted"><span class="ng-tns-c532567586-55">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-55 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-55 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-55"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-55"></div></div></div>```javascript
// Retorna a la pàgina anterior
function anarEnrere() {
    history.back();
}

// Recarrega la pàgina actual amb un truc
function recarregar() {
    history.go(0);
}

// Torna dues pàgines enrere (útil si vols forçar l'usuari a saltar una transició)
setTimeout(() => {
    history.go(-2);
}, 5000);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-55 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-55"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-55"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### 2. Single Page Applications (SPAs) amb `pushState()`

Aquest és el cas d'ús més important de l'API History. Quan un usuari fa clic a un enllaç en una SPA, normalment carregues contingut nou amb AJAX sense recarregar. Però vols que la barra d'adreces mostri la URL correcta (`/usuari/perfil`) i que els botons Enrere/Endavant funcionin.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-56 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-56 ng-star-inserted"><span class="ng-tns-c532567586-56">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-56 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-56 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-56"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-56"></div></div></div>```javascript
function carregarPerfilUsuari(id) {
    // 1. Carregar les dades de l'usuari amb AJAX o Fetch
    // ... (Codi per actualitzar la interfície d'usuari) ...
    
    const nouEstat = {
        userId: id,
        vista: 'perfil'
    };
    const novaURL = `/usuari/${id}`;
    
    // 2. Afegir una nova entrada a l'historial sense recarregar la pàgina
    history.pushState(nouEstat, 'Pàgina de Perfil', novaURL);

    console.log(`Nova entrada a l'historial: ${novaURL}`);
}

// Exemple d'ús:
// L'URL actual és: https://meuweb.cat/inici
carregarPerfilUsuari(101);
// La nova URL a la barra d'adreces és: https://meuweb.cat/usuari/101
// La pàgina NO s'ha recarregat.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-56 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-56"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-56"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>### 3. Modificació de l'estat actual amb `replaceState()`

S'utilitza per actualitzar l'estat de l'entrada actual (per exemple, un filtre de cerca) sense crear una nova entrada a l'historial.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-57 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-57 ng-star-inserted"><span class="ng-tns-c532567586-57">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-57 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-57 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-57"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-57"></div></div></div>```javascript
function aplicarFiltre(criteri) {
    // 1. Carregar les dades filtrades
    // ... (Codi per actualitzar la llista de productes) ...
    
    const nouEstat = {
        criteriFiltre: criteri,
        timestamp: Date.now()
    };
    const novaURL = `/?filtre=${criteri}`;

    // 2. Modificar l'entrada ACTUAL de l'historial.
    history.replaceState(nouEstat, 'Productes Filtrats', novaURL);

    console.log(`Estat de l'historial actualitzat a: ${criteri}`);
}

// L'usuari fa una cerca:
aplicarFiltre('ofertes'); 
// La URL canvia a: /?filtre=ofertes. No es crea una nova entrada a l'historial.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-57 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-57"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-57"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### 4. Gestió de l'esdeveniment `popstate`

Quan l'usuari fa clic als botons "Enrere" o "Endavant" del navegador, es dispara l'esdeveniment **`popstate`**. Aquest esdeveniment és vital en SPAs per carregar el contingut correcte.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-58 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-58 ng-star-inserted"><span class="ng-tns-c532567586-58">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-58 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-58 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-58"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-58"></div></div></div>```javascript
window.addEventListener('popstate', (event) => {
    // L'objecte state conté les dades que vas passar amb pushState() o replaceState()
    const estatAnterior = event.state; 

    if (estatAnterior && estatAnterior.vista === 'perfil') {
        console.log(`Tornant al perfil de l'usuari ${estatAnterior.userId}`);
        // Codi per carregar el perfil usant les dades de l'estat.
    } else {
        console.log("Tornant a una pàgina bàsica (o la pàgina d'inici)");
        // Codi per gestionar la navegació a una URL que no té un estat personalitzat.
    }
    
    console.log(`L'URL actual és: ${location.pathname + location.search}`);
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-58 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c65c02ed6a49fd78","c_3942556f22833484",null,"rc_a7b7da3c3d242159",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-58"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-58"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div>Aquest cicle de **`pushState()` + `popstate`** és el que permet que les aplicacions modernes (com Gmail, Twitter, o qualsevol *framework* de *frontend* com React, Vue o Angular) gestionin les rutes sense recàrregues completes, oferint una experiència d'usuari ràpida i fluida.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--12" inline-copy-host=""></div><p class="callout info">La funció **`addEventListener()`** és un mètode fonamental de JavaScript que permet registrar una funció **(el *listener* o gestor d'esdeveniments)** que serà cridada cada vegada que un **esdeveniment** especificat (com un clic de ratolí, una pulsació de tecla, o una càrrega de pàgina) succeeixi sobre un **objecte concret del DOM** (Document Object Model), com un botó, un formulari, o l'objecte `window`. Aquesta funció pren típicament tres arguments: el **tipus d'esdeveniment** (p. ex., `'click'`), la **funció a executar** quan l'esdeveniment passa, i opcionalment, un booleà o objecte per definir si la captura s'ha de fer durant la fase de *captura* o de *bombolleig* (sent la fase de *bombolleig* l'opció per defecte), permetent una programació no intrusiva i mantenint la lògica de JavaScript separada de l'estructura HTML.</p>

# Objecte navigator

L'objecte **`navigator`** de JavaScript és un objecte del **BOM (Browser Object Model)** que proporciona informació sobre el **navegador** de l'usuari i l'**estat del sistema** on s'executa. És el teu punt d'accés per obtenir dades sobre quin programari està utilitzant l'usuari (el nom i la versió del navegador) i quines capacitats té el dispositiu (geolocalització, connexió a Internet, etc.).

Pots accedir-hi mitjançant `window.navigator` o, simplement, `navigator`.

## Propietats de `navigator`

Les propietats principals de `navigator` es divideixen en informació bàsica (compatibilitat) i informació avançada (estat del sistema/capacitats).

### Propietats d'informació i compatibilitat (Legacy)

Aquestes propietats solien ser molt usades, però avui dia estan desaconsellades per a la detecció de navegadors específica a causa de la suplantació (*spoofing*) i la manca de precisió. Són de només lectura.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 18.5968%;">Propietat</td><td style="width: 40.0444%;">Descripció</td><td style="width: 41.4779%;">Exemple de Valor</td></tr></thead><tbody><tr><td style="width: 18.5968%;">**`userAgent`**</td><td style="width: 40.0444%;">Retorna la cadena completa de l'agent d'usuari (user agent) enviada pel navegador.</td><td style="width: 41.4779%;">`'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/117.0.0.0 Safari/537.36'`</td></tr><tr><td style="width: 18.5968%;">**`appName`**</td><td style="width: 40.0444%;">El nom oficial de l'aplicació. Històricament, retorna gairebé sempre `'Netscape'` per raons de compatibilitat.</td><td style="width: 41.4779%;">`'Netscape'`</td></tr><tr><td style="width: 18.5968%;">**`appVersion`**</td><td style="width: 40.0444%;">La versió del navegador, sovint poc fiable.</td><td style="width: 41.4779%;">`'5.0 (Windows)'`</td></tr><tr><td style="width: 18.5968%;">**`platform`**</td><td style="width: 40.0444%;">La plataforma del sistema operatiu on s'està executant el navegador.</td><td style="width: 41.4779%;">`'Win32'`, `'MacIntel'`, `'Linux x86_64'`</td></tr><tr><td style="width: 18.5968%;">**`cookieEnabled`**</td><td style="width: 40.0444%;">Un booleà que indica si les *cookies* estan habilitades al navegador (`true` o `false`).</td><td style="width: 41.4779%;">`true`</td></tr><tr><td style="width: 18.5968%;">**`language`**</td><td style="width: 40.0444%;">La configuració de llengua preferida del navegador (p. ex., `'ca'`, `'en-US'`).</td><td style="width: 41.4779%;">`'ca-ES'`</td></tr></tbody></table>

</div>### Propietats de capacitat i estat del sistema (Modernes)

Aquestes propietats accedeixen a funcionalitats i estats específics del dispositiu o el navegador.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3-1" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 19.7897%;">Propietat</td><td style="width: 43.6191%;">Descripció</td><td style="width: 36.5912%;">Cas d'Ús</td></tr></thead><tbody><tr><td style="width: 19.7897%;">**`onLine`**</td><td style="width: 43.6191%;">Un booleà que indica l'estat de la connexió a Internet (`true` si està *online*).</td><td style="width: 36.5912%;">Comprovar si es pot sincronitzar dades amb un servidor.</td></tr><tr><td style="width: 19.7897%;">**`geolocation`**</td><td style="width: 43.6191%;">Un objecte que conté mètodes per obtenir la ubicació geogràfica de l'usuari.</td><td style="width: 36.5912%;">Sol·licitar coordenades GPS per mostrar un mapa.</td></tr><tr><td style="width: 19.7897%;">**`mediaDevices`**</td><td style="width: 43.6191%;">Un objecte que proporciona accés a càmeres, micròfons i altres dispositius multimèdia.</td><td style="width: 36.5912%;">Desenvolupar aplicacions de videoconferència o càmera web.</td></tr><tr><td style="width: 19.7897%;">**`clipboard`**</td><td style="width: 43.6191%;">API per llegir i escriure contingut al porta-retalls.</td><td style="width: 36.5912%;">Implementar un botó de "Copiar URL".</td></tr><tr><td style="width: 19.7897%;">**`storage`**</td><td style="width: 43.6191%;">API per gestionar la quota d'emmagatzematge persistent.</td><td style="width: 36.5912%;">Comprovar l'espai disponible per a dades *offline*.</td></tr><tr><td style="width: 19.7897%;">**`vendor`**</td><td style="width: 43.6191%;">El venedor del navegador (sovint buit o poc fiable, excepte per a Chrome).</td><td style="width: 36.5912%;">`'Google Inc.'`</td></tr><tr><td style="width: 19.7897%;">**`maxTouchPoints`**</td><td style="width: 43.6191%;">El nombre màxim de punts de contacte simultanis (tocs) compatibles amb el dispositiu.</td><td style="width: 36.5912%;">Detectar si el dispositiu és tàctil per ajustar la interfície.</td></tr></tbody></table>

  
</div>## Mètodes de `navigator`

A diferència de `location` i `history`, `navigator` té pocs mètodes directes a l'objecte base. La majoria de les funcionalitats s'implementen mitjançant mètodes dels sub-objectes (com `navigator.geolocation` o `navigator.mediaDevices`).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ca" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 21.4483%;">Mètode</td><td style="width: 41.7221%;">Descripció</td><td style="width: 36.8296%;">Cas d'Ús</td></tr></thead><tbody><tr><td style="width: 21.4483%;">**`javaEnabled()`**</td><td style="width: 41.7221%;">Retorna un booleà que indica si Java està habilitat. (Moltes vegades retorna `false` o no està suportat).</td><td style="width: 36.8296%;">Comprovació de compatibilitat de components *legacy* (desaconsellat).</td></tr><tr><td style="width: 21.4483%;">**`getBattery()`**</td><td style="width: 41.7221%;">Mètode que permet accedir a l'estat de la bateria (obsolet/no disponible en tots els navegadors).</td><td style="width: 36.8296%;">Utilitzat per reduir el consum d'energia de la pàgina si la bateria és baixa.</td></tr><tr><td style="width: 21.4483%;">**`vibrate(pattern)`**</td><td style="width: 41.7221%;">Fes vibrar el dispositiu de l'usuari (si és compatible).</td><td style="width: 36.8296%;">Notificacions tàctils en aplicacions mòbils.</td></tr></tbody></table>

</div>## Exemples i casos d'ús

### 1. Detecció de connexió Online/Offline

Aquest és un cas d'ús molt important per a les aplicacions *offline*.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-81 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-81 ng-star-inserted"><span class="ng-tns-c532567586-81">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-81 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-81 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-81"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-81"></div></div></div>```javascript
function comprovarEstatConnexio() {
    if (navigator.onLine) {
        console.log("Estàs connectat a Internet. Sincronitzant dades...");
    } else {
        console.log("Estàs fora de línia. Les dades es desaran localment.");
    }
}

// També pots utilitzar esdeveniments per reaccionar als canvis
window.addEventListener('online', () => {
    console.log("Connexió RESTABLIDA.");
});
window.addEventListener('offline', () => {
    console.log("Connexió PERDUDA.");
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-81 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-81"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-81"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### 2. Geolocalització (`navigator.geolocation`)

Permet obtenir la posició de l'usuari amb el seu consentiment.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-82 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-82 ng-star-inserted"><span class="ng-tns-c532567586-82">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-82 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-82 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-82"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-82"></div></div></div>```javascript
function obtenirPosicio() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            // Funció d'èxit
            (posicio) => {
                const latitud = posicio.coords.latitude;
                const longitud = posicio.coords.longitude;
                console.log(`Posició: ${latitud}, ${longitud}`);
            },
            // Funció d'error
            (error) => {
                console.error(`Error de geo-localització: ${error.code}`);
            }
        );
    } else {
        console.error("El teu navegador no suporta la geolocalització.");
    }
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-82 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-82"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-82"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>### 3. Detecció de llengua i configuració

Per oferir la versió correcta de la pàgina.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-83 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-83 ng-star-inserted"><span class="ng-tns-c532567586-83">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-83 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-83 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-83"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-83"></div></div></div>```javascript
const idiomaPreferit = navigator.language; // Ex: 'ca-ES'
const idiomaBase = idiomaPreferit.split('-')[0]; // Ex: 'ca'

if (idiomaBase === 'ca') {
    console.log("Mostrant contingut en català.");
} else if (idiomaBase === 'es') {
    console.log("Mostrant contingut en castellà.");
} else {
    console.log("Utilitzant l'anglès com a idioma per defecte.");
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-83 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-83"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-83"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### 4. Detecció de dispositius tàctils

Per oferir controls més grans o una interfície diferent.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-84 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-84 ng-star-inserted"><span class="ng-tns-c532567586-84">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-84 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-84 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-84"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-84"></div></div></div>```javascript
// La propietat 'maxTouchPoints' és un bon indicador, però hi ha altres mètodes
const esTactil = navigator.maxTouchPoints > 0;

if (esTactil) {
    document.body.classList.add('interficie-tactil');
    console.log("Interfície optimitzada per a tàctil.");
} else {
    console.log("Interfície per a ratolí/teclat.");
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-84 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d051474f679f92f0","c_3942556f22833484",null,"rc_36ed6c0c912ffecf",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-84"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-84"></div></div></div>### 5. Accedir càmera `navigator.mediaDevices` (Càmera i Micròfon). 

L'objecte `mediaDevices` proporciona accés als dispositius d'entrada multimèdia (càmera i micròfon) mitjançant l'API **`MediaDevices`**. El mètode clau és `getUserMedia()`, que sol·licita permís a l'usuari.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-102 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-102 ng-star-inserted"><span class="ng-tns-c532567586-102">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-102 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-102 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-102"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-102"></div></div></div>```javascript
// Obté l'element <video> del DOM
const videoElement = document.getElementById('myVideo');

function activarCamera() {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        // Sol·licita accés al vídeo
        navigator.mediaDevices.getUserMedia({ video: true, audio: false })
            .then(stream => {
                // Connecta el flux de vídeo a l'element <video>
                videoElement.srcObject = stream;
                videoElement.play();
                console.log("Càmera activada correctament.");
            })
            .catch(error => {
                // Gestió d'errors (p. ex., usuari denega el permís)
                console.error("No s'ha pogut accedir a la càmera: ", error);
            });
    } else {
        console.error("El navegador no suporta MediaDevices API.");
    }
}

// Cas d'ús: En una aplicació de videoconferència o un escàner de codis QR.
// Però caldria afegir un `<button onclick="activarCamera()">Activar Càmera</button>`
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-102 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-102"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-102"></div></div></div>### 6. Porta-retalls `navigator.clipboard` 

L'API **`Clipboard`** permet llegir i escriure text al porta-retalls del sistema de manera asíncrona, requerint el permís de l'usuari en la majoria dels casos per raons de seguretat. **Exemple**: Escriure (Copiar) al Porta-retalls

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--13" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-103 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-103 ng-star-inserted"><span class="ng-tns-c532567586-103">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-103 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-103 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-103"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-103"></div></div></div>```javascript
const textACopiar = "Aquesta és l'URL que vull compartir.";

function copiarAlPortaRetalls(text) {
    if (navigator.clipboard) {
        // Utilitza el mètode asíncron writeText
        navigator.clipboard.writeText(text)
            .then(() => {
                alert(`"${text}" copiat al porta-retalls!`);
            })
            .catch(err => {
                console.error('No s\'ha pogut copiar el text: ', err);
            });
    } else {
        // Fallback per a navegadors antics (utilitzant document.execCommand)
        console.warn("Clipboard API no suportada. Utilitzant mètode antic.");
    }
}

// Cas d'ús: Implementar un botó de "Copiar enllaç" o "Copiar codi" fàcil.
// copiarAlPortaRetalls(textACopiar);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-103 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--14" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-103"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-103"></div></div></div>### 7. Gestió emmagatzematge `navigator.storage`

L'**emmagatzemament persistent** en el context d'una aplicació web es refereix a la capacitat d'una pàgina web o una aplicació web progressiva (**PWA**) de sol·licitar al navegador que **protegeixi les dades emmagatzemades localment** (com les bases de dades IndexedDB, l'API Cache o Web Storage) per evitar que siguin eliminades automàticament pel navegador en situacions de baixa memòria o d'espai d'emmagatzematge limitat. A diferència de l'emmagatzemament normal, que es considera "millor esforç" (*best effort*) i pot ser esborrat sense previ avís, l'emmagatzemament persistent (**`navigator.storage.persist()`**) garanteix que les dades crucials d'una aplicació (com el contingut *offline* o la configuració d'usuari) romanguin segures al dispositiu de l'usuari a llarg termini, millorant la fiabilitat de l'experiència *offline*.

L'objecte `storage` proporciona mètodes per gestionar l'emmagatzematge del lloc web, com ara el **càlcul de la quota d'emmagatzematge** i la **sol·licitud d'emmagatzematge persistent**. **Exemple**: Comprovar la Quota d'Emmagatzematge

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--15" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-104 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-104 ng-star-inserted"><span class="ng-tns-c532567586-104">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-104 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-104 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-104"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-104"></div></div></div>```javascript
function comprovarQuota() {
    if (navigator.storage && navigator.storage.estimate) {
        // Utilitza el mètode estimate() per obtenir l'ús actual i la quota total
        navigator.storage.estimate()
            .then(estimacio => {
                const usMB = (estimacio.usage / 1024 / 1024).toFixed(2);
                const quotaMB = (estimacio.quota / 1024 / 1024).toFixed(2);
                
                console.log(`Ús actual: ${usMB} MB`);
                console.log(`Quota total: ${quotaMB} MB`);
                
                const percentatgeUs = ((estimacio.usage / estimacio.quota) * 100).toFixed(2);
                console.log(`Usat: ${percentatgeUs}%`);
            });
    } else {
        console.warn("El mètode navigator.storage.estimate() no està disponible.");
    }
}

// Cas d'ús: Aplicacions web progressives (PWA) que necessiten emmagatzemar dades 
// grans offline (IndexedDB, Cache API) i comprovar si tenen espai per guardar-les.
// comprovarQuota();
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-104 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--16" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-104"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-104"></div></div></div>### 8. Informació navegador (`navigator.userAgent`) 

La cadena **`userAgent`** és un identificador enviat pel navegador a cada servidor web, i actua com el "document d'identitat" digital del client. La seva estructura és històricament complexa i sovint poc precisa a causa de les necessitats de compatibilitat (*spoofing*). En una cadena `userAgent` típica, hi podem trobar diverses seccions clau que proporcionen informació sobre:

#### Informació del navegador i motor de renderització

La major part de la cadena se centra en identificar el programari utilitzat per l'usuari per visualitzar el contingut web:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-identificador-de-com" inline-copy-host="">- **Identificador de Compatibilitat (Legacy):** Gairebé sempre comença amb **`Mozilla/5.0`**. Això es manté per raons històriques, ja que molts llocs antics requerien el navegador Netscape (Mozilla) per funcionar.
- **Motor de Renderització:** Indica el motor que utilitza el navegador per interpretar l'HTML i el CSS. Per exemple:
    
    
    - **`AppleWebKit/XXX`**: Utilitzat per navegadors basats en Chromium (Chrome, Edge, Opera) i Safari.
    - **`Gecko/XXX`**: Utilitzat per Firefox.
- **Nom i Versió del Navegador:** Es pot trobar el nom real del navegador i la seva versió, tot i que sovint s'emmascaren:
    
    
    - **`Chrome/XXX`** (per a Google Chrome o Edge basat en Chromium).
    - **`Firefox/XXX`** (per a Mozilla Firefox).
    - **`Safari/XXX`** (per a Apple Safari).

  
</div>#### Informació del SSOO i Plataforma

Aquesta secció especifica l'entorn de programari i *hardware* on s'executa el navegador:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-sistema-operatiu-%28os" inline-copy-host="">- **Sistema Operatiu (OS):** Identifica l'OS. Exemples:
    
    
    - **`Windows NT 10.0`** (per a Windows 10/11).
    - **`Macintosh; Intel Mac OS X 10_15`** (per a macOS).
    - **`X11; Linux x86_64`** (per a sistemes Linux).
- **Tipus de Dispositiu:** Indica si és un dispositiu mòbil, de taula, o una tauleta:
    
    
    - **`Mobi`** (una etiqueta comú per a dispositius mòbils).
    - **`Android XXX`** (per a telèfons/tauletes Android).

</div>#### Exemple `userAgent`

Aquí hi ha un exemple típic de cadena `userAgent` desglossada:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--17" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-122 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--18" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_e04fd76f897918d1","c_3942556f22833484",null,"rc_f411fd0955a14e98",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-122"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-122"></div></div></div>```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-122 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--19" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_e04fd76f897918d1","c_3942556f22833484",null,"rc_f411fd0955a14e98",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-122"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-122"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-segment-informaci%C3%B3-s" inline-copy-host=""><table><thead><tr><td>Segment</td><td>Informació</td><td>Significat</td></tr></thead><tbody><tr><td>`Mozilla/5.0`</td><td>**Compatibilitat**</td><td>Identificador històric.</td></tr><tr><td>`(Windows NT 10.0; Win64; x64)`</td><td>**Sistema Operatiu**</td><td>Windows 10/11, arquitectura 64-bit.</td></tr><tr><td>`AppleWebKit/537.36`</td><td>**Motor de Renderització**</td><td>Usant el motor WebKit.</td></tr><tr><td>`(KHTML, like Gecko)`</td><td>**Compatibilitat**</td><td>Més referències històriques per dir "sóc compatible amb tot".</td></tr><tr><td>`Chrome/120.0.0.0`</td><td>**Navegador Principal**</td><td>És Google Chrome, versió 120.</td></tr><tr><td>`Safari/537.36`</td><td>**Identificador Secundari**</td><td>S'inclou per compatibilitat amb llocs que busquen Safari.</td></tr></tbody></table>

</div>**Casos d'Ús:** Històricament, es feia servir per oferir contingut específic a cada navegador o dispositiu, però avui dia s'utilitza principalment per a **anàlisi i *logging*** de trànsit web i errors. Per detectar funcionalitats (com la càmera o la geolocalització), és molt més recomanable utilitzar la **detecció de característiques** (p. ex., comprovant si `navigator.geolocation` existeix).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--20" inline-copy-host=""></div>La propietat `userAgent` retorna la cadena que el navegador envia al servidor per identificar-se. Tot i que està desaconsellada per a la detecció de funcionalitats (és millor fer detecció de característiques, no de navegadors!), segueix sent útil per a registres i certes necessitats. **Exemple**: Analitzar la Cadena `userAgent`

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--21" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-105 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-105 ng-star-inserted"><span class="ng-tns-c532567586-105">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-105 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-105 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-105"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-105"></div></div></div>```javascript
const userAgentString = navigator.userAgent;
let missatge = `La cadena de l'agent d'usuari és: ${userAgentString}`;

// Cas d'ús: Detecció simple (i sovint imprecisa) de mòbil.
// NOTA: Per a detecció de mòbil, és millor fer-ho basat en mitjans CSS o altres propietats
// com navigator.maxTouchPoints.

if (userAgentString.includes('Mobi') || userAgentString.includes('Android')) {
    missatge += "\nSembla que l'usuari està utilitzant un dispositiu mòbil.";
} else {
    missatge += "\nSembla que l'usuari està utilitzant un escriptori.";
}

console.log(missatge);

// Cas d'ús: Enviar aquesta informació al servidor juntament amb els logs d'error
// per entendre l'entorn on s'ha produït un problema.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-105 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--22" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_53fe57f80dee92f3","c_3942556f22833484",null,"rc_213248991eb05d93",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-105"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-105"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--23" inline-copy-host=""></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--25" inline-copy-host=""></div>

# Objecte screen

L'objecte **`screen`** de JavaScript és un objecte del **BOM (Browser Object Model)** que proporciona informació sobre la **pantalla o el monitor** de l'usuari que executa el navegador web. A diferència de l'objecte `window`, que informa sobre la finestra del navegador, `screen` informa sobre les dimensions i la profunditat de color del dispositiu de visualització real.

Pots accedir-hi mitjançant `window.screen` o, simplement, `screen`.

## Propietats de `screen`

Totes les propietats de l'objecte `screen` són de **només lectura** i s'expressen en **píxels**.

### 1. Dimensions totals de la pantalla

Aquestes propietats indiquen la resolució total de la pantalla del dispositiu.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Exemple</td></tr></thead><tbody><tr><td>**`width`**</td><td>L'amplada total de la pantalla en píxels.</td><td>`1920`</td></tr><tr><td>**`height`**</td><td>L'alçada total de la pantalla en píxels.</td><td>`1080`</td></tr></tbody></table>

</div>### 2. Dimensions disponibles (sense barra tasques)

Aquestes propietats indiquen l'espai real de la pantalla que el navegador pot utilitzar, ja que exclouen elements fixes del sistema operatiu (com la barra de tasques o les dreceres).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3-1" inline-copy-host=""><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Exemple</td></tr></thead><tbody><tr><td>**`availWidth`**</td><td>L'amplada de la pantalla disponible (excloent barres del sistema).</td><td>`1920`</td></tr><tr><td>**`availHeight`**</td><td>L'alçada de la pantalla disponible (excloent barres del sistema).</td><td>`1040`</td></tr></tbody></table>

</div>### 3. Profunditat de color

Aquestes propietats són útils per a la compatibilitat de colors, tot i que avui dia la majoria dels dispositius utilitzen una alta profunditat de color.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3-2" inline-copy-host=""><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Exemple</td></tr></thead><tbody><tr><td>**`colorDepth`**</td><td>Retorna el nombre de bits utilitzats per mostrar un color. Normalment `24` o `32`.</td><td>`24`</td></tr><tr><td>**`pixelDepth`**</td><td>Retorna la resolució de color de la pantalla en bits. Normalment és el mateix que `colorDepth`.</td><td>`24`</td></tr></tbody></table>

</div>## Mètodes/Funcions de `screen`

Actualment, l'objecte `screen` no té mètodes propis àmpliament utilitzats o estandarditzats per manipular directament la pantalla. Totes les interaccions es basen en la lectura de les seves propietats. Les úniques funcions que històricament han estat associades o relacionades amb la pantalla (tot i que formen part de l'objecte `window`) són les que gestionen la finestra mateixa:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-window.moveto%28x%2C-y%29%3A" inline-copy-host="">- **`window.moveTo(x, y)`:** Mou la finestra actual a les coordenades ![](https://siensis.com/books/uploads/images/gallery/2025-09/HwtmQQAf5ELgBVsm-embedded-image-eb1swpq5.png) especificades a la pantalla.
- **`window.resizeTo(amplada, alçada)`:** Redimensiona la finestra actual a les dimensions especificades.

</div><p class="callout warning">**Nota:** L'ús d'aquests mètodes per manipular la finestra està **molt restringit** pels navegadors moderns per raons de seguretat i d'experiència d'usuari, especialment en finestres que no han estat creades per l'script mateix (`window.open()`).</p>

## Exemples i casos d'ús

### Detecció de resolució 

El cas d'ús més comú és detectar la resolució total o disponible per adaptar funcionalitats o notificar a l'usuari.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-137 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-137 ng-star-inserted"><span class="ng-tns-c532567586-137">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-137 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-137 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-137"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-137"></div></div></div>```javascript
console.log(`Resolució total del monitor: ${screen.width} x ${screen.height}`);
console.log(`Àrea utilitzable (sense barres del sistema): ${screen.availWidth} x ${screen.availHeight}`);

// Cas d'ús: Alertar sobre resolucions molt baixes
if (screen.width < 1024) {
    document.getElementById('avís').textContent = "Aquesta web no està optimitzada per a la teva baixa resolució de pantalla.";
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-137 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-137"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-137"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### Optimització de Finestra o Pop-ups

Quan es crea una nova finestra emergent (pop-up), es pot utilitzar `screen.width` i `screen.height` per centrar-la o dimensionar-la de manera òptima.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-138 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-138 ng-star-inserted"><span class="ng-tns-c532567586-138">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-138 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-138 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-138"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-138"></div></div></div>```javascript
function obrirFinestraCentrada(url) {
    const ampleFinestra = 800;
    const alturaFinestra = 600;

    // Calcula les coordenades per centrar la finestra a l'àrea disponible
    const centreX = (screen.availWidth - ampleFinestra) / 2;
    const centreY = (screen.availHeight - alturaFinestra) / 2;

    const especificacions = `width=${ampleFinestra},height=${alturaFinestra},left=${centreX},top=${centreY}`;

    window.open(url, 'FinestraPopup', especificacions);
}

// Cas d'ús: Obrir una finestra de login o de confirmació amb dimensions fixes i centrada.
// obrirFinestraCentrada('login.html');
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-138 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-138"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-138"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div><p class="callout info">[Més informació a `window.open`](https://siensis.com/books/books/1-introduccio-al-javascript/page/objecte-window-lRb)</p>

###  Detecció de Profunditat de Color

Encara que poc comú avui dia, en el passat era útil per decidir si mostrar imatges d'alta qualitat o una versió simplificada.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-139 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-139 ng-star-inserted"><span class="ng-tns-c532567586-139">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-139 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-139 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-139"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-139"></div></div></div>```javascript
console.log(`Profunditat de color: ${screen.colorDepth} bits`);

if (screen.colorDepth < 16) {
    console.warn("Pantalla amb colors limitats. Es desactiven els efectes de color complexos.");
    // Codi per carregar imatges en 16 bits en lloc de 24.
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-139 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-139"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-139"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### Detecció d'Orientació (Mòbils)

Tot i que l'objecte `screen` conté les dimensions, l'API per detectar i bloquejar l'orientació del dispositiu (vertical o horitzontal) resideix a **`screen.orientation`** (un sub-objecte).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-140 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-140 ng-star-inserted"><span class="ng-tns-c532567586-140">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-140 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-140 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-140"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-140"></div></div></div>```javascript
// Obté l'orientació actual (p. ex., 'portrait-primary' o 'landscape-primary')
console.log(`Orientació actual: ${screen.orientation.type}`);

// Cas d'ús: Bloquejar l'orientació en un joc web
function bloquejarOrientacio() {
    if (screen.orientation && screen.orientation.lock) {
        screen.orientation.lock('landscape')
            .then(() => console.log("Orientació bloquejada a horitzontal."))
            .catch(error => console.error("No es pot bloquejar l'orientació:", error));
    }
}

// També es pot reaccionar als canvis d'orientació amb un listener
screen.orientation.addEventListener('change', () => {
    console.log(`L'usuari ha girat la pantalla a: ${screen.orientation.type}`);
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-140 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_2fa6a36284d3fa6a","c_3942556f22833484",null,"rc_b262ebf5f158295f",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-140"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-140"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div>

# Objectes storage

L'objecte **`Storage`** de JavaScript, accessible mitjançant **`localStorage`** i **`sessionStorage`**, forma part de l'API Web Storage i s'utilitza per emmagatzemar dades clau-valor localment al navegador de l'usuari. És una alternativa més moderna i amb més capacitat que les *cookies* per a l'emmagatzematge de dades persistents de la sessió o a llarg termini.

## Tipus d'emmagatzematge web

Hi ha dos tipus d'objectes `Storage`, que comparteixen les mateixes propietats i mètodes, però difereixen en la seva persistència:

### `localStorage` (Emmagatzematge persistent)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-persist%C3%A8ncia%3A-les-da" inline-copy-host="">- **Persistència:** Les dades es mantenen **fins que l'usuari les esborra manualment** (a través de la configuració del navegador o el codi). Romanen disponibles fins i tot després de tancar i reobrir el navegador.
- **Cas d'Ús:** Preferències d'usuari (tema fosc/clar), tokens d'autenticació (amb precaució), dades *offline*, historial de carrets de compra.

</div>### `sessionStorage` (Emmagatzematge de sessió)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-persist%C3%A8ncia%3A-les-da-1" inline-copy-host="">- **Persistència:** Les dades es mantenen **només durant la sessió de la pestanya o finestra actual**. Quan l'usuari tanca la pestanya o la finestra, les dades s'esborren automàticament.
- **Cas d'Ús:** Dades temporals de la sessió, estat de formularis incomplets, estat de la navegació en una sessió.

</div>## Propietats i mètodes

Tant `localStorage` com `sessionStorage` implementen la mateixa interfície `Storage`. Totes les dades s'emmagatzemen com a **parells clau-valor de tipus *string***.

### Propietats

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table><thead><tr><td>Propietat</td><td>Descripció</td><td>Exemple</td></tr></thead><tbody><tr><td>**`length`**</td><td>Retorna el nombre de parells clau-valor emmagatzemats a l'objecte `Storage` actual.</td><td>`3`</td></tr></tbody></table>

</div>### Mètodes

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-se" inline-copy-host=""><table><thead><tr><td>Mètode</td><td>Descripció</td></tr></thead><tbody><tr><td>**`setItem(clau, valor)`**</td><td>Afegeix el parell clau-valor a l'emmagatzematge. Si la clau ja existeix, el valor antic es sobreescriu.</td></tr><tr><td>**`getItem(clau)`**</td><td>Retorna el valor associat a la clau especificada. Retorna `null` si la clau no es troba.</td></tr><tr><td>**`removeItem(clau)`**</td><td>Elimina el parell clau-valor amb la clau especificada de l'emmagatzematge.</td></tr><tr><td>**`clear()`**</td><td>Elimina **tots** els parells clau-valor de l'objecte `Storage` (tot el `localStorage` o tot el `sessionStorage`).</td></tr><tr><td>**`key(index)`**</td><td>Retorna la clau de l'índex especificat (útil per iterar sobre totes les dades).</td></tr></tbody></table>

  
</div>## Exemples d'ús

### Emmagatzemar dades simples (Strings)

Totes les dades s'emmagatzemen com a *strings*.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-205 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-205 ng-star-inserted"><span class="ng-tns-c532567586-205">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-205 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-205 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-205"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-205"></div></div></div>```javascript
// Utilitzem localStorage
localStorage.setItem('usuari_nom', 'Jordi');
localStorage.setItem('data_login', '2025-09-30');

// Recuperar un valor
const nom = localStorage.getItem('usuari_nom'); // Resultat: "Jordi"

// Eliminar un element
localStorage.removeItem('data_login');

// Comprovar la mida
console.log(localStorage.length); // Resultat: 1 (només queda 'usuari_nom')
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-205 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-205"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-205"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### 2. Emmagatzemar objectes o arrays (Necessita Serialització)

Com que `Storage` només accepta *strings*, cal convertir els objectes JavaScript a format JSON (*string*) abans de guardar-los i des-serialitzar-los quan es recuperen.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-206 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-206 ng-star-inserted"><span class="ng-tns-c532567586-206">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-206 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-206 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-206"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-206"></div></div></div>```javascript
const configuracio = {
    tema: 'fosc',
    notificacions: true,
    idioma: 'ca'
};

// 🔸 GUARDAR (Serialització a JSON string)
localStorage.setItem('config_usuari', JSON.stringify(configuracio));

// 🔸 RECUPERAR (Des-serialització a Objecte JavaScript)
const configGuardadaJSON = localStorage.getItem('config_usuari');

if (configGuardadaJSON) {
    const configObjecte = JSON.parse(configGuardadaJSON);
    console.log(configObjecte.tema); // Resultat: "fosc"
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-206 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-206"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-206"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>### 3. Iterar sobre l'emmagatzematge

Pots recórrer tots els elements utilitzant la propietat `length` i el mètode `key()`.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-207 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-207 ng-star-inserted"><span class="ng-tns-c532567586-207">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-207 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-207 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-207"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-207"></div></div></div>```javascript
console.log("Elements de la sessió actual:");

for (let i = 0; i < sessionStorage.length; i++) {
    const clau = sessionStorage.key(i);
    const valor = sessionStorage.getItem(clau);
    console.log(`Clau: ${clau}, Valor: ${valor}`);
}

// Cas d'ús: Auditar o depurar el contingut emmagatzemat.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-207 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-207"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-207"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### Neteja de l'emmagatzematge

S'utilitza per esborrar totes les dades emmagatzemades al domini actual.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-208 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-208 ng-star-inserted"><span class="ng-tns-c532567586-208">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-208 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-208 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-208"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-208"></div></div></div>```javascript
// ATENCIÓ: Esborra TOT el localStorage
function tancarSessio() {
    localStorage.clear();
    sessionStorage.clear();
    console.log("Tots els elements de storage eliminats.");
    // Redirigir a la pàgina de login o inici
    // location.href = '/login';
}
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-208 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0ad2ffa6687aac40","c_3942556f22833484",null,"rc_c695743db935c357",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-208"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-208"></div></div></div>## Seguretat i Límits

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-l%C3%ADmits-de-mida%3A-la-m" inline-copy-host="">- **Límits de mida:** La majoria dels navegadors permeten emmagatzemar entre **5 MB i 10 MB** de dades per domini. Si se supera el límit, es llança una excepció.
- **Seguretat (XSS):** Les dades emmagatzemades a `localStorage` **no són segures contra atacs *Cross-Site Scripting* (XSS)**. Qualsevol *script* maliciós injectat a la pàgina pot llegir-les. Per això, no s'hauria d'emmagatzemar informació altament sensible com ara contrasenyes o tokens d'autenticació de llarga durada.
- **Àmbit (Scope):** `localStorage` i `sessionStorage` estan restringits al **mateix origen** (protocol, host, i port). Els scripts d'un domini no poden accedir a l'emmagatzematge d'un altre.
- **Sincronia:** Les operacions són síncrones i poden bloquejar el fil d'execució principal (main thread) si es llegeixen o escriuen grans quantitats de dades. Per a dades molt grans o complexes, es recomana utilitzar **IndexedDB**.

</div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div>## IndexedDB (BBDD al navegador)

El Web Storage (com **`localStorage`** i **`sessionStorage`**) és excel·lent per a dades clau-valor petites i simples. Tanmateix, per a l'emmagatzematge de dades estructurades, grans volums d'informació, o la necessitat de consultar i indexar registres, JavaScript ofereix una opció molt més robusta: **IndexedDB**.

**IndexedDB** és una **API asíncrona** de JavaScript per a un emmagatzematge de dades a gran escala i altament estructurat al costat del client. És, essencialment, un sistema de base de dades NoSQL transaccional que resideix al navegador de l'usuari.

### Característiques

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-emmagatzematge-as%C3%ADnc" inline-copy-host="">1. **Emmagatzematge asíncron:** Totes les operacions són asíncrones i basades en esdeveniments (o promeses si s'utilitzen llibreries o *wrappers* moderns). Això significa que **no bloquegen el fil d'execució principal** de JavaScript (a diferència de `localStorage`), la qual cosa és crucial per mantenir la fluïdesa de la interfície d'usuari.
2. **NoSQL (Orientada a Objectes):** Emmagatzema objectes JavaScript de manera nativa, utilitzant **claus** per a la indexació i la recuperació. No treballa amb taules i SQL, sinó amb **magatzems d'objectes** (*Object Stores*).
3. **Transaccional:** Totes les modificacions es realitzen dins de **transaccions**. Això garanteix la integritat de les dades: si una part de l'operació falla, tota la transacció es desfà.
4. **Capacitat:** Els límits d'emmagatzematge solen ser molt més alts que els de `localStorage` (sovint entre el 50% i el 80% de l'espai lliure del disc, amb un mínim garantit de 250 MB o més), i és l'emmagatzematge preferit per a les **Progressive Web Apps (PWA)**.

</div>### Components

IndexedDB es basa en conceptes que reflecteixen les bases de dades tradicionals:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-component-concepte-f" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 19.6663%;">Component</td><td style="width: 44.8033%;">Concepte</td><td style="width: 35.5304%;">Funció</td></tr></thead><tbody><tr><td style="width: 19.6663%;">**`Database`**</td><td style="width: 44.8033%;">La base de dades pròpiament dita (l'equivalent al fitxer de BD).</td><td style="width: 35.5304%;">Es defineix amb un nom (p. ex., 'LaMevaAppDB') i una versió.</td></tr><tr><td style="width: 19.6663%;">**`Object Store`**</td><td style="width: 44.8033%;">La unitat principal d'emmagatzematge (l'equivalent a una taula).</td><td style="width: 35.5304%;">Conté els registres (objectes).</td></tr><tr><td style="width: 19.6663%;">**`Index`**</td><td style="width: 44.8033%;">Un punter a una propietat específica dels objectes.</td><td style="width: 35.5304%;">Permet la cerca i la recuperació ràpida de dades basades en aquesta propietat (no només per la clau primària).</td></tr><tr><td style="width: 19.6663%;">**`Transaction`**</td><td style="width: 44.8033%;">Un embolcall que garanteix que un conjunt d'operacions s'executen completament o no s'executen en absolut.</td><td style="width: 35.5304%;">Pot ser de lectura (`readonly`) o d'escriptura (`readwrite`).</td></tr></tbody></table>

</div>### Mètodes i operacions

L'API IndexedDB és complexa i es basa principalment en mètodes de l'objecte `IDBRequest` (per gestionar les sol·licituds) i l'objecte `IDBTransaction`.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-operaci%C3%B3-m%C3%A8tode-%2F-pr" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 14.6684%;">Operació</td><td style="width: 37.6558%;">Mètode / Propietat Clau</td><td style="width: 47.6758%;">Descripció</td></tr></thead><tbody><tr><td style="width: 14.6684%;">**Obrir BD**</td><td style="width: 37.6558%;">`indexedDB.open(nom, versió)`</td><td style="width: 47.6758%;">Inicia la connexió a la base de dades. Requereix gestionar l'esdeveniment `onupgradeneeded` per crear o modificar els *Object Stores*.</td></tr><tr><td style="width: 14.6684%;">**Afegir**</td><td style="width: 37.6558%;">`objectStore.add(objecte, clau)`</td><td style="width: 47.6758%;">Afegeix un nou objecte al magatzem.</td></tr><tr><td style="width: 14.6684%;">**Recuperar**</td><td style="width: 37.6558%;">`objectStore.get(clau)`</td><td style="width: 47.6758%;">Recupera un objecte pel seu identificador de clau.</td></tr><tr><td style="width: 14.6684%;">**Actualitzar**</td><td style="width: 37.6558%;">`objectStore.put(objecte, clau)`</td><td style="width: 47.6758%;">Actualitza un objecte existent o l'afegeix si no existeix.</td></tr><tr><td style="width: 14.6684%;">**Esborrar**</td><td style="width: 37.6558%;">`objectStore.delete(clau)`</td><td style="width: 47.6758%;">Elimina un registre pel seu identificador de clau.</td></tr><tr><td style="width: 14.6684%;">**Cursor**</td><td style="width: 37.6558%;">`objectStore.openCursor()`</td><td style="width: 47.6758%;">Permet iterar eficientment sobre grans conjunts de dades o utilitzar índexs per a la cerca avançada.</td></tr></tbody></table>

</div>### Casos d'ús

A causa de la seva complexitat, IndexedDB s'utilitza principalment quan `localStorage` no és suficient:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-dades-offline-extens" inline-copy-host="">1. **Dades *Offline* Extenses:** Emmagatzematge del cos de missatges o el contingut d'articles sencers per llegir sense connexió.
2. **Cerca ràpida (Indexació):** Aplicacions que necessiten cercar ràpidament registres grans (p. ex., productes en un catàleg o contactes en una llibreta).
3. **Emmagatzematge d'arxius grans:** Capacitat per emmagatzemar objectes binaris grans (`Blob`s), cosa que permet guardar imatges o fitxers de so.
4. **Frameworks i llibreries:** Els *frameworks* de *frontend* moderns (com Angular, React) o llibreries de dades *offline* (com PouchDB) solen utilitzar IndexedDB per sota de la superfície.

</div>### Exemple de recuperació de dades

L'API nativa és molt detallada, però conceptualment es veu així:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--12" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-220 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d1dd1d6c62e823b8","c_3942556f22833484",null,"rc_1d7fada77b97f5da",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-220 ng-star-inserted"><span class="ng-tns-c532567586-220">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-220 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-220 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-220"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-220"></div></div></div>```javascript
// 1. Obtenir la connexió a la base de dades
const request = indexedDB.open('CatalegProductes', 1);

request.onerror = function(event) {
  console.error("Error en obrir la base de dades");
};

request.onsuccess = function(event) {
  const db = event.target.result;
  
  // 2. Iniciar una transacció de lectura
  const transaccio = db.transaction(['productes'], 'readonly');
  const store = transaccio.objectStore('productes');
  
  // 3. Demanar la recuperació d'una clau
  const getRequest = store.get(123);

  getRequest.onsuccess = function(event) {
    console.log("Producte recuperat:", event.target.result);
  };
};

// Aquest procés és asíncron i no bloqueja la UI.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-220 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--13" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_d1dd1d6c62e823b8","c_3942556f22833484",null,"rc_1d7fada77b97f5da",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-220"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-220"></div></div></div>### Exemple complet IndexedDB (catàleg llibres)

```javascript
// Nom i versió de la base de dades
const DB_NAME = 'CatalegLlibresDB';
const DB_VERSION = 1;
const STORE_NAME = 'llibres'; // El nostre magatzem d'objectes (la "taula")

let db; // Variable global per a la connexió a la base de dades

// --- 1. OBRIR I CREAR LA BASE DE DADES (Si no existeix) ---

function obrirDB() {
    return new Promise((resolve, reject) => {
        // Sol·licita obrir la base de dades
        const request = indexedDB.open(DB_NAME, DB_VERSION);

        // Aquest esdeveniment es dispara si la versió de la DB no existeix o és inferior
        request.onupgradeneeded = (event) => {
            db = event.target.result;
            console.log(`Creant o actualitzant magatzem d'objectes: ${STORE_NAME}`);
            
            // Creem l'Object Store (la "taula")
            // Definim 'isbn' com a clau primària (keyPath)
            if (!db.objectStoreNames.contains(STORE_NAME)) {
                db.createObjectStore(STORE_NAME, { keyPath: 'isbn' });
                // També podríem crear un índex per a cerques per 'autor', per exemple
                // store.createIndex('per_autor', 'autor', { unique: false }); 
            }
        };

        request.onsuccess = (event) => {
            db = event.target.result;
            console.log("Base de dades oberta amb èxit!");
            resolve();
        };

        request.onerror = (event) => {
            console.error("Error en obrir la base de dades:", event.target.errorCode);
            reject(new Error("No es pot obrir la DB"));
        };
    });
}

// --- 2. AFegir ELEMENTS (CRUD: Create) ---

function afegirLlibre(llibre) {
    if (!db) {
        console.error("La base de dades no està connectada.");
        return;
    }
    
    // 1. Iniciar una transacció de lectura/escriptura
    const transaccio = db.transaction([STORE_NAME], 'readwrite');
    const store = transaccio.objectStore(STORE_NAME);
    
    // 2. Afegir l'objecte
    const request = store.add(llibre);

    request.onsuccess = () => {
        console.log(`Llibre afegit amb ISBN ${llibre.isbn}`);
    };

    request.onerror = (event) => {
        // Això passa sovint si ja existeix un element amb la mateixa clau (ISBN)
        console.error("Error en afegir el llibre:", event.target.error);
    };
}

// --- 3. CONSULTAR UN ELEMENT PER CLAU (CRUD: Read) ---

function consultarLlibre(isbn) {
    if (!db) {
        console.error("La base de dades no està connectada.");
        return;
    }
    
    // 1. Iniciar una transacció de només lectura
    const transaccio = db.transaction([STORE_NAME], 'readonly');
    const store = transaccio.objectStore(STORE_NAME);
    
    // 2. Recuperar l'element per la seva clau primària (ISBN)
    const request = store.get(isbn);

    request.onsuccess = (event) => {
        const llibre = event.target.result;
        if (llibre) {
            console.log(`\n--- Llibre trobat (ISBN ${isbn}) ---`);
            console.log(llibre);
        } else {
            console.log(`\nNo s'ha trobat cap llibre amb ISBN ${isbn}`);
        }
    };

    request.onerror = (event) => {
        console.error("Error en consultar el llibre:", event.target.error);
    };
}

// --- 4. ELIMINAR UN ELEMENT PER CLAU (CRUD: Delete) ---

function eliminarLlibre(isbn) {
    if (!db) {
        console.error("La base de dades no està connectada.");
        return;
    }

    // 1. Iniciar una transacció de lectura/escriptura
    const transaccio = db.transaction([STORE_NAME], 'readwrite');
    const store = transaccio.objectStore(STORE_NAME);
    
    // 2. Eliminar l'element per la seva clau primària (ISBN)
    const request = store.delete(isbn);

    request.onsuccess = () => {
        console.log(`\nLlibre amb ISBN ${isbn} eliminat correctament.`);
    };

    request.onerror = (event) => {
        console.error("Error en eliminar el llibre:", event.target.error);
    };
}


// --- FLUX D'EXECUCIÓ (Async/Await per simplificar) ---

const llibre1 = { isbn: '978-8426102604', titol: 'El petit príncep', autor: 'Antoine de Saint-Exupéry', any: 1943 };
const llibre2 = { isbn: '978-8429749103', titol: 'Tirant lo Blanc', autor: 'Joanot Martorell', any: 1490 };

// Esperem a que la base de dades estigui oberta abans de fer operacions
obrirDB()
    .then(() => {
        // Afegeix el llibre 1
        afegirLlibre(llibre1);
        
        // Afegeix el llibre 2
        afegirLlibre(llibre2);
        
        // Consulta el llibre 1 després d'un petit retard (per assegurar-nos que s'ha escrit)
        setTimeout(() => consultarLlibre('978-8426102604'), 500);
        
        // Intentem consultar un ISBN que no existeix
        setTimeout(() => consultarLlibre('111-2223334445'), 1000);
        
        // Elimina el llibre 2
        setTimeout(() => eliminarLlibre('978-8429749103'), 1500);

        // Comprovem que s'ha eliminat
        setTimeout(() => consultarLlibre('978-8429749103'), 2000);
    })
    .catch((error) => {
        console.error("No es pot continuar. La DB no s'ha pogut inicialitzar.");
    });
```

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--14" inline-copy-host=""></div>

# Document Object Model (DOM)

El DOM (Document Object Model) és una interfície de programació d'aplicacions (API) que s'utilitza per a documents HTML i XML. Essencialment, és la representació estructurada i orientada a objectes de la pàgina web que permet als programes (principalment JavaScript) accedir al contingut, l'estructura i els estils del document i manipular-los de manera dinàmica.

**El DOM com a Estructura d'Arbre**

El DOM no és la pàgina HTML en si, sinó un model d'arbre jeràrquic creat pel navegador. Cada part de l'estructura del document (etiquetes, text, atributs) es converteix en un node.

- **Node Arrel**: El document sencer (document)
- **Nodes d'Element**: Representen les etiquetes HTML (p. ex., &lt;body&gt;, &lt;div&gt;, &lt;p&gt;)
- **Nodes d'Atribut**: Representen els atributs de les etiquetes (p. ex., class="actiu")
- **Nodes de Text**: Representen el text que hi ha dins dels elements.

Aquesta estructura d'arbre defineix les relacions pare-fill i germà entre els elements.

**Funcionalitat Principal**

La funció principal del DOM és fer que la pàgina web sigui interactiva:

- **Accés i Selecció**: JavaScript pot trobar qualsevol element de la pàgina
- **Manipulació de Contingut**: Permet llegir o modificar el contingut d'un element
- **Gestió d'Esdeveniments**: Permet assignar funcions (listeners) als elements per reaccionar a les interaccions de l'usuari
- **Manipulació de l'Estructura**: Permet afegir nous elements o eliminar-ne d'existents

# DOM Element

Un **Element DOM** (Document Object Model) és la representació, dins de l'estructura d'arbre jeràrquic del DOM, d'una **etiqueta HTML específica** (p. ex., un `<div>`, un `<p>`, un `<img>`, o un `<button>`). Quan el navegador carrega una pàgina HTML, crea una representació de cada etiqueta com un node que es pot manipular. L'Element DOM és el tipus de node més comú i important, ja que encapsula totes les dades estructurals, d'estil i de comportament associades a la seva etiqueta HTML corresponent.

Tots els elements del DOM, a més d'heretar mètodes i propietats de tipus de nodes superiors (`Node` i `EventTarget`), tenen mètodes i propietats específiques que permeten gestionar-ne el contingut, els atributs i la posició a la pàgina.

## Mètodes implementats en un element DOM

Els mètodes d'un Element DOM es poden dividir en diverses categories funcionals:

### Manipulació d'Atributs

Aquests mètodes permeten llegir, modificar i eliminar els atributs HTML d'un element (com `id`, `class`, `href`, `src`).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-ge" inline-copy-host=""><table><thead><tr><td>Mètode</td><td>Descripció</td></tr></thead><tbody><tr><td>**`getAttribute(nom)`**</td><td>Retorna el valor actual de l'atribut especificat.</td></tr><tr><td>**`setAttribute(nom, valor)`**</td><td>Estableix el valor de l'atribut especificat. Si l'atribut no existeix, el crea.</td></tr><tr><td>**`hasAttribute(nom)`**</td><td>Retorna `true` si l'element té l'atribut especificat.</td></tr><tr><td>**`removeAttribute(nom)`**</td><td>Elimina l'atribut amb el nom especificat.</td></tr></tbody></table>

</div>### Manipulació de Classes

Els Elements DOM tenen la propietat **`classList`**, que és una col·lecció de mètodes dedicats a gestionar les classes CSS de l'element sense manipular directament la cadena `className`.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-%28element.clas" inline-copy-host=""><table><thead><tr><td>Mètode (`element.classList.`)</td><td>Descripció</td></tr></thead><tbody><tr><td>**`add(nomClasse)`**</td><td>Afegeix una o més classes a l'element.</td></tr><tr><td>**`remove(nomClasse)`**</td><td>Elimina una o més classes de l'element.</td></tr><tr><td>**`toggle(nomClasse, força?)`**</td><td>Commuta la presència de la classe. Si s'afegeix `true` com a segon argument, obliga l'addició.</td></tr><tr><td>**`contains(nomClasse)`**</td><td>Retorna `true` si l'element té la classe especificada.</td></tr></tbody></table>

</div>### Creació i manipulació de nodes

Aquests mètodes permeten modificar l'estructura de l'arbre DOM (afegir o eliminar elements fills).

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-m%C3%A8tode-descripci%C3%B3-%2A%2A" inline-copy-host=""><table><thead><tr><td>Mètode</td><td>Descripció</td></tr></thead><tbody><tr><td>\*\*`append(node</td><td>string)`\*\*</td></tr><tr><td>\*\*`prepend(node</td><td>string)`\*\*</td></tr><tr><td>**`appendChild(node)`**</td><td>Afegeix un node com a últim fill de l'element (mètode tradicional).</td></tr><tr><td>**`removeChild(node)`**</td><td>Elimina un node fill especificat de l'element.</td></tr><tr><td>**`insertAdjacentHTML(posició, html)`**</td><td>Analitza una cadena HTML i insereix els nodes resultants a una posició específica (abans/després de l'element, o a l'inici/final del seu contingut).</td></tr></tbody></table>

</div>## Algunes propietats en un element DOM

Les propietats defineixen l'estat, el contingut i l'estructura de l'Element DOM.

### Contingut i estil

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 24.0624%;">Propietat</td><td style="width: 75.9376%;">Descripció</td></tr></thead><tbody><tr><td style="width: 24.0624%;">**`id`**</td><td style="width: 75.9376%;">Retorna o estableix l'atribut `id` de l'element.</td></tr><tr><td style="width: 24.0624%;">**`className`**</td><td style="width: 75.9376%;">Retorna o estableix la llista de classes com una cadena (*string*) (p. ex., `'actiu primari'`).</td></tr><tr><td style="width: 24.0624%;">**`classList`**</td><td style="width: 75.9376%;">Retorna l'objecte `DOMTokenList` que permet gestionar les classes (vegeu mètodes de classes).</td></tr><tr><td style="width: 24.0624%;">**`innerHTML`**</td><td style="width: 75.9376%;">Obté o defineix el contingut HTML **dins** de l'element. (Permet inserir *scripts* si es fa amb precaució).</td></tr><tr><td style="width: 24.0624%;">**`textContent`**</td><td style="width: 75.9376%;">Obté o defineix el contingut de text **pur** de l'element i els seus descendents. (Segur contra injecció d'HTML).</td></tr><tr><td style="width: 24.0624%;">**`value`**</td><td style="width: 75.9376%;">Retorna o defineix el valor actual d'un element de formulari (`<input>`, `<textarea>`, `<select>`).</td></tr><tr><td style="width: 24.0624%;">**`style`**</td><td style="width: 75.9376%;">Retorna l'objecte **`CSSStyleDeclaration`** per manipular els estils CSS en línia (p. ex., `element.style.color = 'red';`).</td></tr></tbody></table>

</div>### Estructura i relacions

Aquestes propietats permeten navegar pel DOM.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-propietat-descripci%C3%B3-1" inline-copy-host=""><table style="width: 87.0238%;"><thead><tr><td style="width: 24.7885%;">Propietat</td><td style="width: 75.2115%;">Descripció</td></tr></thead><tbody><tr><td style="width: 24.7885%;">**`parentElement`**</td><td style="width: 75.2115%;">Retorna el node pare immediat.</td></tr><tr><td style="width: 24.7885%;">**`children`**</td><td style="width: 75.2115%;">Retorna una col·lecció dels elements fills directes (només elements, excloent nodes de text).</td></tr><tr><td style="width: 24.7885%;">**`firstElementChild`**</td><td style="width: 75.2115%;">Retorna el primer element fill.</td></tr><tr><td style="width: 24.7885%;">**`lastElementChild`**</td><td style="width: 75.2115%;">Retorna l'últim element fill.</td></tr></tbody></table>

</div>## Exemples i casos d'ús

Suposem que tenim el següent element al nostre HTML:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-265 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-html" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-265 ng-star-inserted"><span class="ng-tns-c532567586-265">HTML</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-265 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-265 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-265"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-265"></div></div></div>```javascript
<button id="btnNotificacio" data-count="0" class="boto-primari">
    Mostra Notificacions
</button>
<div id="resultat"></div>
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-265 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-265"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-265"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>### Manipulació d'atributs i classes

**Cas d'Ús:** Implementar un comptador de clics que actualitzi un atribut de dades i un estil.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-266 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-266 ng-star-inserted"><span class="ng-tns-c532567586-266">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-266 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-266 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-266"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-266"></div></div></div>```javascript
const btn = document.getElementById('btnNotificacio');
let comptador = 0;

btn.addEventListener('click', () => {
    // 1. Modificar contingut
    comptador++;
    btn.textContent = `Notificacions (${comptador})`;

    // 2. Modificar un atribut de dades (data-count)
    btn.setAttribute('data-count', comptador);

    // 3. Modificar classes
    if (comptador > 5) {
        btn.classList.add('alerta'); // Afegeix la classe per estils d'alerta
    } else {
        btn.classList.remove('alerta'); // Assegura que s'elimina
    }
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-266 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-266"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-266"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>### Creació i Inserció de Contingut

**Cas d'Ús:** Afegir dinàmicament una llista d'elements.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-267 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-267 ng-star-inserted"><span class="ng-tns-c532567586-267">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-267 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-267 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-267"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-267"></div></div></div>```javascript
const resultatDiv = document.getElementById('resultat');

function crearLlista(items) {
    // 1. Netejar contingut anterior
    resultatDiv.innerHTML = '';
    
    // 2. Crear un nou element <ul>
    const ul = document.createElement('ul');

    items.forEach(itemText => {
        const li = document.createElement('li');
        
        // Utilitzar textContent per seguretat (no es poden injectar scripts)
        li.textContent = itemText; 
        
        // 3. Afegir el <li> al <ul>
        ul.appendChild(li);
    });

    // 4. Afegir el <ul> al <div> principal
    resultatDiv.append(ul);
}

crearLlista(['poma', 'plàtan', 'taronja']);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-267 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-267"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-267"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>### Modificació d'estils en línia

**Cas d'Ús:** Canviar el color de fons basat en un estat.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--9" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-268 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-268 ng-star-inserted"><span class="ng-tns-c532567586-268">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-268 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-268 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-268"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-268"></div></div></div>```javascript
const header = document.getElementById('capcalera'); // Suposem que existeix

function canviarEstat(actiu) {
    if (actiu) {
        header.style.backgroundColor = '#4CAF50'; // Verd
        header.style.fontWeight = 'bold';
    } else {
        header.style.backgroundColor = 'transparent';
        header.style.fontWeight = 'normal';
    }
}

// canviarEstat(true);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-268 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--10" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_0c6f91f46d55ebc4","c_3942556f22833484",null,"rc_5c1699b86a8c0ae3",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-268"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-268"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--11" inline-copy-host=""></div>

# DOM + Frameworks = VDOM (Virtual DOM)

El **Virtual DOM (VDOM)** és un concepte de programació utilitzat per *frameworks* de JavaScript moderns com **React, Vue.js i Svelte** per millorar el **rendiment** i l'**eficiència** de les actualitzacions del DOM (Document Object Model) real.

## Què és i com funciona el VDOM?

El VDOM és essencialment una **còpia abstracta i lleugera** de l'estructura del DOM real, emmagatzemada en la memòria del navegador. No és el DOM real, sinó un objecte JavaScript que representa el DOM. El procés d'actualització mitjançant el VDOM segueix tres passos fonamentals:

### 1. Creació i renderitzat inicial

Quan es carrega l'aplicació per primera vegada, el *framework* construeix l'arbre del VDOM basant-se en els components de la interfície d'usuari (UI). Aquest VDOM es sincronitza immediatament amb el DOM real per mostrar la UI.

### 2. Actualització de l'estat i re-renderitzat del VDOM

Quan l'estat de l'aplicació canvia (p. ex., l'usuari fa clic a un botó, o arriba una nova dada del servidor), el *framework* no actualitza el DOM real directament. En lloc d'això, crea un **nou arbre VDOM** que reflecteix l'estat actualitzat.

### 3. El procés de d*iffing* i p*atching* (Detecció de diferències) 

Aquesta és la part més important:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-algoritme-de-diffing" inline-copy-host="">1. **Algoritme de *Diffing*:** El *framework* compara l'**arbre VDOM nou** amb l'**arbre VDOM antic**. Aquesta comparació és molt ràpida perquè es fa amb objectes JavaScript a la memòria (no amb el DOM lent).
2. **Càlcul de *Patch*:** El resultat d'aquesta comparació és un llistat mínim dels **canvis exactes (el *patch*)** que s'han de fer. Per exemple, si només ha canviat el text d'un `<p>` dins d'un `<div>` gran, el *patch* només inclourà l'actualització d'aquest text.
3. **Actualització del DOM Real:** Finalment, el *framework* aplica aquest petit *patch* de canvis directament al **DOM real**.

</div>## Avantatges del virtual DOM

L'ús d'aquesta capa d'abstracció proporciona beneficis significatius:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-rendiment-millorat%3A-" inline-copy-host="">- **Rendiment millorat:** La manipulació del DOM real és l'operació més lenta en una aplicació web. El VDOM minimitza el nombre de vegades que s'ha de tocar el DOM real, garantint que només es fan les operacions estrictament necessàries.
- **Simplicitat per al desenvolupador:** El desenvolupador ja no ha de preocupar-se per manipular manualment el DOM (`getElementById`, `appendChild`, etc.). Simplement ha de declarar **com ha de ser la UI** en funció de l'estat, i el *framework* s'encarrega d'aplicar els canvis de manera eficient.
- **Desenvolupament isomòrfic (SSR):** Permet que el mateix codi de la UI s'executi en entorns diferents, com el servidor (Node.js) per generar HTML inicial (*Server-Side Rendering*), ja que el VDOM és una representació abstracta.

</div><p class="callout info">El **Virtual DOM** actua com un mediador intel·ligent entre l'estat de la vostra aplicació i l'arbre del DOM real, optimitzant les actualitzacions per oferir una experiència d'usuari més fluida i ràpida.</p>

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div>

# DOM event

La taula d'esdeveniments DOM (Document Object Model) mostra els mecanismes crucials que té JavaScript per interactuar amb l'usuari i l'estat del navegador. En lloc de limitar-nos a la taula, ens centrarem en les categories principals d'esdeveniments i destacarem els més importants i d'ús freqüent, amb exemples clars d'ús amb `addEventListener()`.

## Esdeveniments de ratolí (Mouse Events)

Aquests són els esdeveniments més comuns per a la interactivitat bàsica.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-event-descripci%C3%B3-mil" inline-copy-host=""><table><thead><tr><td>Event</td><td>Descripció Millorada</td><td>Cas d'Ús Destacat</td></tr></thead><tbody><tr><td>**`click`**</td><td>Es dispara quan es pressiona i es deixa anar ràpidament el botó principal del ratolí sobre un element.</td><td>És l'esdeveniment fonamental per a la interacció amb botons, enllaços i elements interactius.</td></tr><tr><td>**`dblclick`**</td><td>Es dispara quan l'usuari fa doble clic ràpidament sobre un element.</td><td>S'utilitza per activar edicions o obertures ràpides (p. ex., obrir una carpeta).</td></tr><tr><td>**`mouseover`**</td><td>El punter del ratolí es mou sobre l'element **o sobre qualsevol dels seus fills**.</td><td>Sovint substituït per `mouseenter` per millorar el rendiment.</td></tr><tr><td>**`mouseenter`**</td><td>El punter del ratolí entra a l'element. **No es dispara quan entra als fills**.</td><td>Ideal per mostrar *tooltips* o canviar estils quan el ratolí entra a la zona.</td></tr><tr><td>**`mouseleave`**</td><td>El punter del ratolí surt de l'element.</td><td>Desfer els canvis fets amb `mouseenter`.</td></tr><tr><td>**`mousedown` / `mouseup`**</td><td>Es disparen quan es pressiona / s'allibera el botó del ratolí.</td><td>Útils per implementar funcionalitats de "drag and drop" o per mesurar el temps de retenció del clic.</td></tr></tbody></table>

</div>### Exemple de ratolí (`click` i `mouseenter`)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-244 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-244 ng-star-inserted"><span class="ng-tns-c532567586-244">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-244 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-244 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-244"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-244">  
</div></div></div>```javascript
const boto = document.getElementById('meuBoto');
const missatge = document.getElementById('missatge');

// 1. Esdeveniment click
boto.addEventListener('click', () => {
    alert('Has clicat el botó!');
});

// 2. Esdeveniment mouseenter
boto.addEventListener('mouseenter', () => {
    missatge.textContent = 'Passant el ratolí per sobre...';
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-244 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-244"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-244"></div></div></div>## Esdeveniments de teclat (Keyboard Events)

Essencials per a formularis, dreceres de teclat i jocs.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-event-descripci%C3%B3-mil-1" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 14.4133%;">Event</td><td style="width: 53.048%;">Descripció Millorada</td><td style="width: 32.5387%;">Cas d'Ús Destacat</td></tr></thead><tbody><tr><td style="width: 14.4133%;">**`keydown`**</td><td style="width: 53.048%;">Es dispara quan es pressiona una tecla. Es dispara repetidament si la tecla es manté premuda.</td><td style="width: 32.5387%;">Detecció de dreceres (Ctrl + S), o detecció de tecles no-caràcter (F1, F5).</td></tr><tr><td style="width: 14.4133%;">**`keyup`**</td><td style="width: 53.048%;">Es dispara quan s'allibera una tecla.</td><td style="width: 32.5387%;">Finalitzar la detecció d'una drecera o d'una pulsació.</td></tr><tr><td style="width: 14.4133%;">**`keypress`**</td><td style="width: 53.048%;">**Obsolet/Desaconsellat.** Només es disparava quan es premia una tecla que produïa un caràcter (p. ex., 'A', '1', però no 'Majúscules' o 'Alt').</td><td style="width: 32.5387%;">Usar `keydown` o `input` en el seu lloc.</td></tr></tbody></table>

</div>### Exemple de teclat (`keydown`)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-245 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-245 ng-star-inserted"><span class="ng-tns-c532567586-245">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-245 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-245 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-245"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-245">  
</div></div></div>```javascript
document.addEventListener('keydown', (event) => {
    // La propietat 'key' retorna la tecla premuda
    if (event.key === 'Enter') {
        console.log("Usuari ha pressionat Enter. Enviant formulari...");
        // event.preventDefault(); // Evita l'acció per defecte
    }
    // Per a dreceres:
    if (event.ctrlKey && event.key === 'd') {
        event.preventDefault(); // Bloqueja el comportament per defecte del navegador
        alert("Drecera Ctrl+D activada!");
    }
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-245 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-245"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-245"></div></div></div>## Esdeveniments de formulari i entrada (Form &amp; Input Events)

Controlen la interacció amb camps de text, seleccions i l'enviament de dades.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-event-descripci%C3%B3-mil-2" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 17.7592%;">Event</td><td style="width: 47.1942%;">Descripció Millorada</td><td style="width: 35.0465%;">Cas d'Ús Destacat</td></tr></thead><tbody><tr><td style="width: 17.7592%;">**`change`**</td><td style="width: 47.1942%;">Es dispara quan un element de formulari **perd el focus** (amb `blur`) i el seu valor ha estat modificat des de l'últim focus.</td><td style="width: 35.0465%;">Validació final de camp, o canvi en `<select>`.</td></tr><tr><td style="width: 17.7592%;">**`input`**</td><td style="width: 47.1942%;">Es dispara immediatament cada vegada que el valor d'un camp canvia (es prem una tecla, es fa una retallada, etc.).</td><td style="width: 35.0465%;">Validació instantània en temps real, comptadors de caràcters.</td></tr><tr><td style="width: 17.7592%;">**`focus` / `blur`**</td><td style="width: 47.1942%;">Es dispara quan un element rep / perd el focus (es fa clic a dins / es fa clic a fora).</td><td style="width: 35.0465%;">Canviar l'estil visual del camp actiu.</td></tr><tr><td style="width: 17.7592%;">**`submit`**</td><td style="width: 47.1942%;">Es dispara quan s'intenta enviar un `<form>`.</td><td style="width: 35.0465%;">Interceptar l'enviament per fer una validació de dades final abans d'enviar-les al servidor.</td></tr></tbody></table>

</div>### Exemple de formulari (`input` i `submit`)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--4" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-246 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-246 ng-star-inserted"><span class="ng-tns-c532567586-246">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-246 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-246 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-246"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-246">  
</div></div></div>```javascript
const campNom = document.getElementById('nom');
const formulari = document.getElementById('meuForm');

// 1. Esdeveniment input (Validació en temps real)
campNom.addEventListener('input', () => {
    if (campNom.value.length < 3) {
        console.log("El nom ha de tenir almenys 3 caràcters.");
    }
});

// 2. Esdeveniment submit (Validació final)
formulari.addEventListener('submit', (event) => {
    if (campNom.value.length === 0) {
        event.preventDefault(); // Evita que el formulari s'enviï
        alert('El camp Nom és obligatori!');
    }
    // Si la validació és OK, el formulari s'envia
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-246 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-246"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-246"></div></div></div>## Esdeveniments de finestra i document (Window &amp; Document Events)

Aquests esdeveniments estan relacionats amb l'estat del navegador, l'URL i el procés de càrrega.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-event-descripci%C3%B3-mil-3" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 19.893%;">Event</td><td style="width: 41.9663%;">Descripció Millorada</td><td style="width: 38.0215%;">Cas d'Ús Destacat</td></tr></thead><tbody><tr><td style="width: 19.893%;">**`load`**</td><td style="width: 41.9663%;">Es dispara quan la **pàgina sencera** (incloent-hi tots els recursos: imatges, scripts, CSS) ha acabat de carregar-se.</td><td style="width: 38.0215%;">Iniciar el codi principal de l'aplicació o inicialitzar *scripts* de tercers.</td></tr><tr><td style="width: 19.893%;">**`DOMContentLoaded`**</td><td style="width: 41.9663%;">Es dispara quan **el document HTML ha estat completament carregat i parsejat**, sense esperar els estils ni les imatges.</td><td style="width: 38.0215%;">Recomanat per iniciar la lògica JavaScript, ja que és més ràpid que `load`.</td></tr><tr><td style="width: 19.893%;">**`resize`**</td><td style="width: 41.9663%;">Es dispara quan la finestra del navegador canvia de mida.</td><td style="width: 38.0215%;">Adaptar la interfície a resolucions canviants o al gir de la pantalla en mòbils.</td></tr><tr><td style="width: 19.893%;">**`scroll`**</td><td style="width: 41.9663%;">Es dispara quan l'usuari fa *scroll* a l'element o a la finestra.</td><td style="width: 38.0215%;">Implementar càrrega infinita (*infinite scroll*) o fixar elements (com una capçalera) en una posició.</td></tr><tr><td style="width: 19.893%;">**`popstate`**</td><td style="width: 41.9663%;">Es dispara quan l'usuari navega a una entrada de l'historial (clicant Enrere/Endavant) després d'haver utilitzat `history.pushState()`.</td><td style="width: 38.0215%;">Essencial per a la gestió de rutes en **SPAs (Single Page Applications)**.</td></tr></tbody></table>

</div>### Exemple de finestra (`DOMContentLoaded` i `resize`)

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-247 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-247 ng-star-inserted"><span class="ng-tns-c532567586-247">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-247 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-247 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-247"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-247">  
</div></div></div>```javascript
// Millor que 'load' per iniciar el JS
document.addEventListener('DOMContentLoaded', () => {
    console.log("L'estructura DOM està llesta.");
    // Aquí inicialitzem listeners d'elements que ja existeixen
});

// Adaptació a la pantalla
window.addEventListener('resize', () => {
    console.log(`Nova amplada de la finestra: ${window.innerWidth}px`);
    // Codi per recalcular la posició d'un mapa o d'un gràfic
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-247 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--7" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_21c9d10d90f5ad2b","c_3942556f22833484",null,"rc_b42fdadc6707aebd",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-247"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-247"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--8" inline-copy-host=""></div>

# DOM Node vs DOM Element

Els conceptes de **Node (Node DOM)** i **Element (Element DOM)** són fonamentals per entendre com funciona l'estructura jeràrquica del DOM (Document Object Model) de JavaScript, tot i que sovint s'utilitzen indistintament. La diferència clau és que **`Node` és el terme genèric i abstracte** per a qualsevol cosa a l'arbre del DOM, mentre que **`Element` és un tipus d'objecte `Node` molt específic** i, sovint, el més important.

## Node DOM (el PARE de tots)

Un **Node** és la **classe base** i l'objecte més genèric en la jerarquia del DOM. Qualsevol cosa en un document HTML o XML és, per definició, un node. Un node pot ser de diversos tipus.

### Tipus de node comuns:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-tipus-de-node-consta" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 11.7998%;">Tipus de Node</td><td style="width: 26.3437%;">Constant JavaScript</td><td style="width: 33.3702%;">Descripció</td><td style="width: 28.4863%;">Exemple en HTML</td></tr></thead><tbody><tr><td style="width: 11.7998%;">**Element**</td><td style="width: 26.3437%;">`Node.ELEMENT_NODE` (1)</td><td style="width: 33.3702%;">Representa una etiqueta HTML, com `<div>`, `<p>`, `<img>`.</td><td style="width: 28.4863%;">`<p class="text">`</td></tr><tr><td style="width: 11.7998%;">**Text**</td><td style="width: 26.3437%;">`Node.TEXT_NODE` (3)</td><td style="width: 33.3702%;">Representa el contingut de text **pur** dins d'un element.</td><td style="width: 28.4863%;">El text dins del `<p>`.</td></tr><tr><td style="width: 11.7998%;">**Comment**</td><td style="width: 26.3437%;">`Node.COMMENT_NODE` (8)</td><td style="width: 33.3702%;">Representa un comentari HTML.</td><td style="width: 28.4863%;">``</td></tr><tr><td style="width: 11.7998%;">**Document**</td><td style="width: 26.3437%;">`Node.DOCUMENT_NODE` (9)</td><td style="width: 33.3702%;">Representa el document sencer (l'objecte `document`).</td><td style="width: 28.4863%;">L'etiqueta `&lt;html&gt;` i tot el seu contingut.</td></tr><tr><td style="width: 11.7998%;">**Attribute**</td><td style="width: 26.3437%;">`Node.ATTRIBUTE\_NODE` (2)</td><td style="width: 33.3702%;">Representa un atribut de l'element (p. ex., `class`).</td><td style="width: 28.4863%;">`class="text"`</td></tr></tbody></table>

</div>**Propietats Clau d'un Node:**

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-nodetype%3A-retorna-el" inline-copy-host="">- **`nodeType`**: Retorna el tipus de node com un número (vegeu la columna anterior).
- **`nodeName`**: Retorna el nom del node (p. ex., `'#text'` per a un node de text, o el nom de l'etiqueta per a un element).
- **`parentNode`**, **`childNodes`**: Propietats per navegar per l'arbre complet (inclou nodes de text i comentaris).

</div>## Element DOM 

Un **Element** és un **subtipus de Node** (el `nodeType` és 1). L'Element representa exclusivament les **etiquetes HTML** tal com es veuen en el codi font. Els Elements són els que tenen atributs HTML (com `id`, `class`, `src`, `href`) i l'estructura visual, per tant, tenen moltes més propietats i mètodes per a la manipulació.

### Funcionalitats específiques d'un Element:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-caracter%C3%ADstica-m%C3%A8tod" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 15.4946%;">Característica</td><td style="width: 30.4979%;">Mètode / Propietat Específica d'Element</td><td style="width: 54.0075%;">Descripció</td></tr></thead><tbody><tr><td style="width: 15.4946%;">**Contingut**</td><td style="width: 30.4979%;">**`innerHTML`**, **`textContent`**</td><td style="width: 54.0075%;">Manipulació del contingut (HTML o text) dins de l'etiqueta.</td></tr><tr><td style="width: 15.4946%;">**Atributs**</td><td style="width: 30.4979%;">**`getAttribute()`**, **`setAttribute()`**</td><td style="width: 54.0075%;">Mètodes dedicats exclusivament a la gestió dels atributs HTML.</td></tr><tr><td style="width: 15.4946%;">**Estils**</td><td style="width: 30.4979%;">**`classList`**</td><td style="width: 54.0075%;">Conjunt de mètodes per manipular les classes CSS.</td></tr><tr><td style="width: 15.4946%;">**Navegació**</td><td style="width: 30.4979%;">**`children`**, **`firstElementChild`**</td><td style="width: 54.0075%;">Propietats per navegar només entre els Elements fills (ignora nodes de text i comentaris, cosa que simplifica la navegació).</td></tr></tbody></table>

</div>## Exemple

Considerem el següent fragment d'HTML:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-292 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-html" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c4b79d52def8dbc3","c_3942556f22833484",null,"rc_116ea4a04acd83b4",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-292 ng-star-inserted"><span class="ng-tns-c532567586-292">HTML</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-292 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-292 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-292"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-292">  
</div></div></div>```html
<div id="contenidor">
    <!-- Comentari HTML -->
    Hola món
    <p>Alguna cosa més.</p>
</div>
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-292 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c4b79d52def8dbc3","c_3942556f22833484",null,"rc_116ea4a04acd83b4",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-292"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-292"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--2" inline-copy-host=""></div>Si seleccionem el `div` i mirem els seus fills:

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--3" inline-copy-host=""></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-293 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c4b79d52def8dbc3","c_3942556f22833484",null,"rc_116ea4a04acd83b4",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-293 ng-star-inserted"><span class="ng-tns-c532567586-293">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-293 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-293 mat-unthemed ng-star-inserted"></button></div></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-293"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-293">  
</div></div></div>```javascript
const contenidor = document.getElementById('contenidor');

// 1. Utilitzant NODES (childNodes)
console.log(contenidor.childNodes.length); 
/*
Llista de nodes (ordenats):
. #text (el salt de línia abans del comentari)
. #comment (el node del comentari)
. #text (el text "Hola món")
. <p> (El node d'ELEMENT)
. #text (el salt de línia després del </p>)
*/

// 2. Utilitzant ELEMENTS (children)
console.log(contenidor.children.length); // Resultat: 1
/*
Llista d'ELEMENTS:
1. <p> (Només l'etiqueta HTML)
*/

// 3. Exemple de mètodes:
// Element té:
contenidor.setAttribute('data-id', '123');
// Node de Text (el fill número 3) NO té 'setAttribute'.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-293 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_c4b79d52def8dbc3","c_3942556f22833484",null,"rc_116ea4a04acd83b4",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-293"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-293"></div></div></div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--5" inline-copy-host=""></div>### Resum de la Diferència

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-concepte-qu%C3%A8-represe" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 12.8671%;">Concepte</td><td style="width: 39.2187%;">Què Representa?</td><td style="width: 47.795%;">Quin Tipus d'Objecte és?</td></tr></thead><tbody><tr><td style="width: 12.8671%;">**Node**</td><td style="width: 39.2187%;">Qualsevol cosa de la pàgina (etiqueta, text, comentari, document).</td><td style="width: 47.795%;">El tipus d'objecte més abstracte.</td></tr><tr><td style="width: 12.8671%;">**Element**</td><td style="width: 39.2187%;">Només una etiqueta HTML (`<div>`, `<span>`, `<button>`, etc.).</td><td style="width: 47.795%;">Un tipus específic de Node, amb molts mètodes i propietats addicionals.</td></tr></tbody></table>

</div>En el treball diari amb JavaScript, els desenvolupadors gairebé sempre volen treballar amb **Elements** (perquè són els que tenen *styling* i atributs). Per això, mètodes com **`querySelector()`** i propietats com **`children`** són tan populars, ja que estan dissenyats per retornar i manipular només els **Elements** i no tots els altres tipus de **Nodes**.

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--6" inline-copy-host=""></div>

# Elements i events

## Esdeveniments de JavaScript

<div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-" inline-copy-host="">  
</div><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk-esdeveniment-descrip" inline-copy-host=""><table style="width: 100%;"><thead><tr><td style="width: 16.6719%;">Esdeveniment</td><td style="width: 36.59%;">Descripció </td><td style="width: 15.6092%;">Elements on s'aplica</td><td style="width: 31.2183%;">Exemple Pràctic</td></tr></thead><tbody><tr><td style="width: 16.6719%;">**`onblur`**</td><td style="width: 36.59%;">S'activa quan un element **perd el focus**. Això passa quan l'usuari fa clic fora de l'element o utilitza la tecla `Tab` per anar a un altre element. Sovint s'utilitza per a la **validació de dades** just després que l'usuari ha acabat d'introduir-les.</td><td style="width: 15.6092%;">`<button>`, `<input>`, `<label>`, `<select>`, `<textarea>`, `<body>`</td><td style="width: 31.2183%;">Verificar si un camp d'e-mail té un format vàlid just quan l'usuari surt del camp.</td></tr><tr><td style="width: 16.6719%;">**`onchange`**</td><td style="width: 36.59%;">S'activa quan el valor d'un element de formulari **ha estat modificat** i, a més, l'element **perd el focus** (similar a `onblur` però només per canvis de valor). En el cas de `<select>`, s'activa immediatament després de fer la selecció.</td><td style="width: 15.6092%;">`<input>`, `<select>`, `<textarea>`</td><td style="width: 31.2183%;">Actualitzar el preu total en un formulari de comanda just després que l'usuari tria una opció del menú desplegable o canvia la quantitat.</td></tr><tr><td style="width: 16.6719%;">**`onclick`**</td><td style="width: 36.59%;">S'activa quan l'usuari **prement i allibera el botó principal del ratolí** sobre un element. És l'esdeveniment més comú per a les interaccions amb botons.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Executar una funció que mostra un missatge emergent (alerta) quan es fa clic a un botó.</td></tr><tr><td style="width: 16.6719%;">**`ondblclick`**</td><td style="width: 36.59%;">S'activa quan l'usuari **fa doble clic** amb el botó principal del ratolí sobre un element.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Permetre que un usuari editi el text d'un element (`<div>` o `<span>`) en fer-hi doble clic.</td></tr><tr><td style="width: 16.6719%;">**`onfocus`**</td><td style="width: 36.59%;">S'activa quan un element **rep el focus**. Això pot ser perquè l'usuari hi fa clic o hi navega amb la tecla `Tab`. Sovint s'utilitza per a **millores d'usabilitat**, com ara destacar el camp actiu.</td><td style="width: 15.6092%;">`<button>`, `<input>`, `<label>`, `<select>`, `<textarea>`, `<body>`</td><td style="width: 31.2183%;">Canviar el color de fons d'un camp de text a un to més clar per indicar a l'usuari on està escrivint.</td></tr><tr><td style="width: 16.6719%;">**`onkeydown`**</td><td style="width: 36.59%;">S'activa **just quan es prem una tecla** i es manté. S'activa repetidament si la tecla es manté premuda. És útil per a accions que han de començar immediatament després de prémer la tecla.</td><td style="width: 15.6092%;">Elements de formulari i `<body>`</td><td style="width: 31.2183%;">Evitar que l'usuari introdueixi caràcters no desitjats (com ara lletres en un camp de número) al moment de la pulsació.</td></tr><tr><td style="width: 16.6719%;">**`onkeypress`**</td><td style="width: 36.59%;">S'activa quan es prem una tecla i es **genera un caràcter** (no s'activa per a tecles com `Shift`, `Alt`, `Ctrl`, `Esc`). Aquest esdeveniment es considera obsolet en favor de `onkeydown` i `onkeyup` en codi modern.</td><td style="width: 15.6092%;">Elements de formulari i `<body>`</td><td style="width: 31.2183%;">**(Ús menys freqüent avui dia)** S'utilitzava per filtrar caràcters introduïts.</td></tr><tr><td style="width: 16.6719%;">**`onkeyup`**</td><td style="width: 36.59%;">S'activa **quan l'usuari allibera una tecla** que havia estat premuda. És útil per a accions que han de passar després que l'usuari ha acabat de prémer la tecla.</td><td style="width: 15.6092%;">Elements de formulari i `<body>`</td><td style="width: 31.2183%;">Implementar la funcionalitat de "cerca en directe" (autocompletar) en un camp de text, on la cerca es fa després de cada caràcter escrit.</td></tr><tr><td style="width: 16.6719%;">**`onload`**</td><td style="width: 36.59%;">S'activa quan un recurs (normalment la **pàgina completa**) **s'ha carregat completament**. Això inclou tot el DOM, imatges, fulls d'estil i scripts.</td><td style="width: 15.6092%;">`<body>`</td><td style="width: 31.2183%;">Iniciar un *slideshow* o executar codi d'inicialització un cop s'ha assegurat que tots els elements de la pàgina estan disponibles.</td></tr><tr><td style="width: 16.6719%;">**`onmousedown`**</td><td style="width: 36.59%;">S'activa **quan l'usuari prem un botó del ratolí** (sense alliberar) sobre un element. Passa abans que `onclick`.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Iniciar l'arrossegament d'un element (*drag-and-drop*) just quan es prem el botó.</td></tr><tr><td style="width: 16.6719%;">**`onmousemove`**</td><td style="width: 36.59%;">S'activa **continuadament** mentre l'usuari **mou el punter del ratolí** sobre un element. Pot generar un gran nombre d'esdeveniments.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Mostrar les coordenades (![](https://siensis.com/books/uploads/images/gallery/2025-09/C2UzjhwUmdgAGiXr-embedded-image-mh3or9kw.png), ![](https://siensis.com/books/uploads/images/gallery/2025-09/TQmptwQyewWoSz6D-embedded-image-tvubxhao.png)) del ratolí en temps real o crear un efecte de "rastreig" amb el ratolí.</td></tr><tr><td style="width: 16.6719%;">**`onmouseout`**</td><td style="width: 36.59%;">S'activa quan el punter del ratolí **surt de l'àrea de l'element** (o entra en un dels seus fills). És l'oposat de `onmouseover`.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Desactivar un efecte visual (com canviar la mida de la lletra) que es va aplicar amb `onmouseover`.</td></tr><tr><td style="width: 16.6719%;">**`onmouseover`**</td><td style="width: 36.59%;">S'activa quan el punter del ratolí **entra a l'àrea de l'element**.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Mostrar un *tooltip* (text d'ajuda) o canviar el color de fons d'un element per indicar que és interactiu (efecte *hover*).</td></tr><tr><td style="width: 16.6719%;">**`onmouseup`**</td><td style="width: 36.59%;">S'activa **quan l'usuari allibera un botó del ratolí** que estava premut. Passa després de `onmousedown`.</td><td style="width: 15.6092%;">Tots els elements</td><td style="width: 31.2183%;">Finalitzar l'arrossegament d'un element (*drag-and-drop*) i col·locar-lo a la nova posició.</td></tr><tr><td style="width: 16.6719%;">**`onreset`**</td><td style="width: 36.59%;">S'activa quan un usuari fa clic en un botó de tipus `reset` per **restablir tots els camps** d'un formulari als seus valors inicials.</td><td style="width: 15.6092%;">`<form>`</td><td style="width: 31.2183%;">Mostrar una confirmació a l'usuari abans de netejar el formulari, preguntant si n'està segur.</td></tr><tr><td style="width: 16.6719%;">**`onresize`**</td><td style="width: 36.59%;">S'activa quan **es redimensiona la finestra** del navegador (l'àrea de visualització, o *viewport*). S'utilitza per ajustar elements de disseny.</td><td style="width: 15.6092%;">`<body>`</td><td style="width: 31.2183%;">Reajustar la posició o el disseny d'un component d'interfície dinàmic per assegurar-se que es veu bé a la nova mida de la finestra.</td></tr><tr><td style="width: 16.6719%;">**`onselect`**</td><td style="width: 36.59%;">S'activa quan l'usuari **selecciona una porció de text** dins d'un camp d'entrada o una àrea de text.</td><td style="width: 15.6092%;">`<input>`, `<textarea>`</td><td style="width: 31.2183%;">Mostrar un missatge a l'usuari amb el text que acaba de seleccionar, oferint-li opcions com "Copiar" o "Cercar".</td></tr><tr><td style="width: 16.6719%;">**`onsubmit`**</td><td style="width: 36.59%;">S'activa quan l'usuari **intenta enviar el formulari**, normalment fent clic al botó de tipus `submit`. S'activa **abans** que les dades s'enviïn al servidor.</td><td style="width: 15.6092%;">`<form>`</td><td style="width: 31.2183%;">Realitzar una **validació final i completa** del formulari abans de permetre l'enviament de les dades. Si la validació falla, es pot cancel·lar l'enviament.</td></tr><tr><td style="width: 16.6719%;">**`onunload`**</td><td style="width: 36.59%;">S'activa **just abans que el document es descarregui** (per exemple, quan es tanca la pestanya o es navega a una altra pàgina). S'utilitza per a tasques de neteja o advertència.</td><td style="width: 15.6092%;">`<body>`</td><td style="width: 31.2183%;">Mostrar un missatge d'advertència ("Els canvis no s'han guardat, voleu sortir?") si l'usuari intenta abandonar la pàgina amb dades sense desar.</td></tr></tbody></table>

</div>## Mètode d'assignació directa (Tradicional)

Aquest mètode consisteix a assignar una funció directament a una propietat de l'element que comença amb `on` (p. ex., `onclick`, `onblur`, `onchange`).

### Assignació Correcta

Quan s'assigna una funció, s'ha d'indicar el **nom de la funció** sense parèntesis. D'aquesta manera, el navegador sap que ha d'executar aquesta funció *només* quan es produeixi l'esdeveniment.

<div id="bkmrk--1"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-40 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-40 ng-star-inserted"><span class="ng-tns-c532567586-40">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-40 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-40"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-40">  
</div></div></div>```javascript
// Funció que es vol executar
function mostraMissatge() {
  alert("S'ha fet clic a l'element!");
}

// Assigna la funció a la propietat 'onclick'
document.getElementById("btn-exemple").onclick = mostraMissatge;
// NOTA: No s'executa 'mostraMissatge()', s'assigna la funció en si.


<button id="btn-exemple" onclick="mostraMissatge()">Boto</button>
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-40 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-40"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-40"></div></div></div><div id="bkmrk--3"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div>### Error comú

Si afegeixes els parèntesis a la funció, l'estàs **executant immediatament** i assignant el **resultat** de la funció a la propietat de l'esdeveniment. Si la funció no retorna res (`undefined`), el navegador no tindrà cap funció per executar quan es produeixi l'esdeveniment real.

<div id="bkmrk--4"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-41 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-1" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-41 ng-star-inserted"><span class="ng-tns-c532567586-41">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-41 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-41"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-41">  
</div></div></div>```javascript
// Això executa la funció IMMEDIATAMENT durant la càrrega de la pàgina
// i assigna el resultat (normalment 'undefined') a .onclick.
document.getElementById("btn-exemple").onclick = mostraMissatge(); // !!!! ERROR !!!!
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-41 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-41"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-41"></div></div></div>## El mètode actual `addEventListener()` 

El mètode **`addEventListener()`** és l'estàndard actual i ofereix molta més flexibilitat i robustesa, ja que permet assignar **múltiples funcions** al mateix esdeveniment d'un mateix element.

### Sintaxi Bàsica

Aquest mètode rep (com a mínim) dos arguments:

<div id="bkmrk-el-nom-de-l%27esdeveni"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host="">1. **El nom de l'esdeveniment** (sense el prefix `on`).
2. **La funció** que s'ha d'executar quan es produeixi l'esdeveniment.

</div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-42 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-2" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-42 ng-star-inserted"><span class="ng-tns-c532567586-42">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-42 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-42"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-42">  
</div></div></div>```javascript
const boto = document.getElementById("btn-modern");

// 1. Primer argument: 'click' (sense 'on')
// 2. Segon argument: la funció (sense parèntesis)
boto.addEventListener('click', mostraMissatge); 
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-42 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-42"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-42"></div></div></div><div id="bkmrk--7"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div>### Avantatges d'utilitzar `addEventListener()`

#### 1. Múltiples Gestionadors (Handler)

Amb l'assignació directa (`.onclick`), només pots assignar una funció. Si n'assignes una altra, sobrescriurà l'anterior. Amb `addEventListener()`, pots afegir tants *handlers* com vulguis:

<div id="bkmrk--8"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-43 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-3" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-43 ng-star-inserted"><span class="ng-tns-c532567586-43">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-43 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-43"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-43">  
</div></div></div>```javascript
boto.addEventListener('click', function() {
  console.log("Acció 1: Canviar color");
});

boto.addEventListener('click', function() {
  console.log("Acció 2: Enviar dades analítiques");
});
// Ambdues accions s'executaran en fer clic.
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-43 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--9" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-43"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-43"></div></div></div><div id="bkmrk--10"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div>#### 2. Funcions Anònimes i Fletxa

Permet utilitzar funcions anònimes o funcions de fletxa (![](https://siensis.com/books/uploads/images/gallery/2025-09/ylE0yWXy1Ch2GneW-embedded-image-2l5kriyp.png)), que són ideals per a codi curt i molt localitzat:

<div id="bkmrk--11"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-44 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-4" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-44 ng-star-inserted"><span class="ng-tns-c532567586-44">JavaScript</span><div _ngcontent-ng-c532567586="" class="buttons ng-tns-c532567586-44 ng-star-inserted"><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-44 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div></div></div>```javascript
document.getElementById("camp-text").addEventListener('blur', (e) => {
  // 'e' és l'objecte d'esdeveniment
  if (e.target.value === "") {
    alert("Aquest camp és obligatori!");
  }
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-44 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--12" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-44"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-44"></div></div></div><div id="bkmrk--13"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div>#### 3. Eliminació de gestionadors

Permet eliminar gestionadors específics mitjançant el mètode **`removeEventListener()`**. Això és impossible amb el mètode d'assignació directa.

<div id="bkmrk--14"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-45 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-5" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-45 ng-star-inserted"><span class="ng-tns-c532567586-45">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-45 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-45"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-45">  
</div></div></div>```javascript
// La funció ha de tenir un nom per poder ser eliminada
function funcioTemporal() {
  alert("Només s'executa una vegada!");
  boto.removeEventListener('click', funcioTemporal); //  S'elimina a si mateixa
}

boto.addEventListener('click', funcioTemporal);
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-45 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--15" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-45"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-45"></div></div></div><div id="bkmrk--16"></div>## 3. Assegurar-se que el DOM està preparat (`onload` vs. `DOMContentLoaded`)

Una pràctica fonamental és assegurar-se que l'element al qual vols assignar l'esdeveniment (`document.getElementById("pinchable")`) ja existeix quan el teu codi JavaScript intenta trobar-lo.

<div id="bkmrk-m%C3%A8tode-descripci%C3%B3-qu"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""><table><thead><tr><td>Mètode</td><td>Descripció</td><td>Quan s'executa</td></tr></thead><tbody><tr><td>**`window.onload`**</td><td>Espera que **tota la pàgina** (HTML, CSS, *scripts*, **imatges** i altres recursos) s'hagi carregat completament.</td><td>Tarda més, ja que espera les imatges, etc.</td></tr><tr><td>**`document.addEventListener('DOMContentLoaded', ...)`**</td><td>Espera només que l'**estructura HTML** (el DOM) estigui completament carregada. Aquest és el **mètode preferit** actualment.</td><td>S'executa molt més ràpid, ja que no espera els recursos externs.</td></tr></tbody></table>

</div></div>### Exemple 

Aquesta és la manera més robusta d'estructurar el codi d'esdeveniments:

<div id="bkmrk--17"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" inline-copy-host=""></div></div><div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-46 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk-javascript-6" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="code-block-decoration header-formatted gds-title-s ng-tns-c532567586-46 ng-star-inserted"><span class="ng-tns-c532567586-46">JavaScript</span><button aria-label="Copiar código" class="mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-mdc-tooltip-trigger copy-button ng-tns-c532567586-46 mat-unthemed _mat-animation-noopable ng-star-inserted"></button></div><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-46"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-46">  
</div></div></div>```javascript
document.addEventListener('DOMContentLoaded', () => {
  // Aquest codi s'executa tan bon punt l'HTML està disponible.
  const elementPinchable = document.getElementById("pinchable");

  if (elementPinchable) {
    elementPinchable.addEventListener('click', mostraMissatge);
    elementPinchable.addEventListener('mouseover', () => {
        console.log("El ratolí ha entrat!");
    });
  }
});
```

<div _ngcontent-ng-c532567586="" class="code-block ng-tns-c532567586-46 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" id="bkmrk--18" jslog="223238;track:impression,attention;BardVeMetadataKey:[["r_52fcfbda4d0b4e0a","c_720813e12d770cea",null,"rc_206b7412abcc8c5b",null,null,"ca",null,1,null,null,1,0]]"><div _ngcontent-ng-c532567586="" class="formatted-code-block-internal-container ng-tns-c532567586-46"><div _ngcontent-ng-c532567586="" class="animated-opacity ng-tns-c532567586-46"></div></div></div><div id="bkmrk--19"><div _ngcontent-ng-c3541026175="" class="markdown markdown-main-panel enable-updated-hr-color" dir="ltr" id="bkmrk--20" inline-copy-host=""></div>  
</div>