W3docs

JavaScript - Estendere le Classi Built-in

Scopri come estendere le classi built-in di JavaScript come Array, Map, Set ed Error per aggiungere comportamenti personalizzati senza modificare i prototipi globali.

Le classi built-in come Array, Map, Set ed Error sono classi ordinarie sotto il cofano, quindi puoi usare extends su di esse proprio come su qualsiasi classe scritta da te. La sottoclasse eredita ogni metodo del genitore e può aggiungere nuovi metodi, sovrascrivere comportamenti o mantenere uno stato aggiuntivo. Questo è un modo pulito per costruire una collezione specializzata (un array che sa come sommare se stesso, una mappa con valori predefiniti) o un tipo di errore specifico per un dominio — senza toccare il prototipo globale, che è l'alternativa più rischiosa descritta in JavaScript: Native Prototypes.

Questo capitolo copre la sintassi di base, come i metodi built-in restituiscono istanze della tua sottoclasse, come Symbol.species ti consente di controllarlo, l'estensione di Error per tipi di errore personalizzati e le avvertenze da conoscere prima di ricorrere a questa tecnica. Se sei nuovo a extends e super, leggi prima JavaScript: Class Inheritance.

Sintassi ed Esempio Base

La sintassi è identica all'estensione di qualsiasi altra classe:

class CustomClass extends BuiltInClass {
  // New methods and properties to extend the built-in class
}

Se la tua sottoclasse definisce un costruttore, devi chiamare super() prima di usare this. Questo consente alla classe genitore di inizializzare correttamente il proprio stato interno e le strutture native — per Array e Map, quello stato interno è ciò che le fa funzionare.

Estendiamo la classe Array con un metodo che somma tutti gli elementi:

javascript— editable

L'istanza si comporta come un array completo — indicizzazione, length, iterazione e ogni metodo di Array funzionano — oltre al metodo sum() che hai aggiunto.

⚠️ Nota: Quando si estende Array, tieni presente che la proprietà length si comporta in modo speciale in JavaScript. In alcuni ambienti, length potrebbe non sincronizzarsi automaticamente con la dimensione effettiva dell'array quando si usano certi metodi nativi. Esegui test approfonditi o considera la composizione se il tracciamento preciso della lunghezza è critico.

I Metodi Built-in Restituiscono Istanze della Tua Sottoclasse

Questa è la parte che rende davvero potente l'estensione di Array: metodi come map, filter e slice che restituiscono un nuovo array restituiscono un'istanza della tua sottoclasse, non un semplice Array. Ciò significa che il nuovo array conserva ancora i tuoi metodi personalizzati.

javascript— editable

Internamente, il motore decide quale costruttore usare attraverso un getter statico speciale chiamato Symbol.species. Per impostazione predefinita Symbol.species restituisce la sottoclasse stessa, motivo per cui filter nell'esempio sopra ha prodotto un ExtendedArray.

Controllare il Tipo Restituito con Symbol.species

A volte vuoi il contrario: metodi come map e filter dovrebbero restituire array semplici, mentre new ExtendedArray(...) ti dà ancora la tua sottoclasse. Sovrascrivi Symbol.species per puntare nuovamente alla classe base:

javascript— editable

Ora arr è un PowerArray con il tuo metodo isEmpty(), ma filter restituisce un Array semplice che non porta più quel metodo. Usa questo quando la tua sottoclasse aggiunge stato nel proprio costruttore che gli array derivati non dovrebbero ereditare. Symbol.species è rispettato anche da Map, Set, ArrayBuffer e Promise.

Migliorare la Classe String

La classe String è un altro oggetto built-in fondamentale che può essere esteso con ulteriori helper per la manipolazione delle stringhe.

Aggiungere una Funzione di Inversione

javascript— editable

⚠️ Nota: Estendere String è generalmente sconsigliato a causa delle stranezze di coercizione da primitivo a oggetto in JavaScript, che possono causare comportamenti imprevisti con i metodi nativi. Per la manipolazione delle stringhe, preferisci le funzioni di utilità o la composizione rispetto all'ereditarietà.

Personalizzare la Classe Map

La classe Map in JavaScript rappresenta una collezione di elementi con chiave, offrendo un mezzo di archiviazione dei dati più avanzato e flessibile rispetto agli object. Estendere la classe Map ci consente di introdurre comportamenti più specializzati.

Implementare un Valore Predefinito

Estensione di Map per restituire un valore predefinito se la chiave non esiste. Nota come il get sovrascritto chiama super.get(key) per raggiungere la vera ricerca di Map:

javascript— editable

Estendere la Classe Error

Un uso comune e pratico di questa funzionalità è la creazione di tipi di errore personalizzati. Creare una sottoclasse di Error ti fornisce un errore con un nome che puoi confrontare con instanceof, pur restando un vero Error (quindi porta un message, uno stack e funziona con try...catch).

javascript— editable

Impostare this.name è importante — controlla come viene stampato l'errore e ti consente di distinguere il tuo tipo di errore da uno generico. Per un trattamento più approfondito, incluso come costruire una gerarchia di classi di errore, consulta JavaScript: Custom Errors, Extending Error.

Best Practice e Considerazioni

Sebbene estendere le classi built-in apra un vasto panorama di possibilità, è fondamentale seguire le best practice per garantire la manutenibilità e la compatibilità del codice.

  • Evita di sovrascrivere i metodi esistenti: Estendere le classi built-in aggiungendo nuovi metodi è generalmente sicuro. Tuttavia, sovrascrivere i metodi esistenti può portare a comportamenti imprevedibili e problemi di compatibilità.
  • Usa solo per esigenze specifiche: Estendi le classi built-in quando c'è un chiaro vantaggio o una necessità. Evita estensioni non necessarie che potrebbero complicare il tuo codebase.
  • Preferisci la composizione o le funzioni di utilità: Nel JavaScript moderno, estendere le classi built-in è spesso superfluo. Usare funzioni helper o la composizione di solito fornisce risultati più puliti e prevedibili senza modificare i componenti interni delle sottoclassi native.
  • Documenta le estensioni chiaramente: Assicurati che qualsiasi estensione alle classi built-in sia ben documentata nel tuo codebase per evitare confusione tra gli altri sviluppatori.

Anche i metodi statici vengono ereditati

Quando usi extends su un built-in, la sottoclasse eredita anche i metodi statici del genitore. Quindi ExtendedArray.from(...) e ExtendedArray.isArray(...) sono disponibili, e i metodi factory statici come Array.from producono istanze della sottoclasse. Questo rispecchia la normale ereditarietà delle classi — consulta JavaScript: Static Properties and Methods per come vengono ereditati i membri statici.

Conclusione

Estendere le classi built-in è un modo pulito per aggiungere comportamenti mirati agli oggetti nativi — un array che somma, una mappa con valori predefiniti, un errore con nome — senza modificare i prototipi globali. L'idea chiave da ricordare è che i metodi built-in derivati restituiscono per impostazione predefinita istanze della tua sottoclasse, e Symbol.species è la leva per cambiare questo comportamento. Ricorri all'ereditarietà quando esiste una vera relazione "è-un"; altrimenti preferisci semplici funzioni di utilità o la composizione.

Pratica

Pratica
Quali affermazioni sono accurate riguardo all'estensione delle classi built-in in JavaScript?
Quali affermazioni sono accurate riguardo all'estensione delle classi built-in in JavaScript?
Was this page helpful?