W3docs

Prototipi Nativi di JavaScript

Scopri come funzionano i prototipi nativi in JavaScript: Object.prototype come radice della catena, prototipi di Array, Function e Number, prestito di metodi con call e apply.

Esplorare i Prototipi Nativi

I prototipi nativi in JavaScript sono gli oggetti che i costruttori predefiniti come Array, Object, String, Number e Function utilizzano per condividere metodi e proprietà con ogni valore che creano. Quando chiami [1, 2, 3].map(...) o "hi".toUpperCase(), il metodo che stai chiamando non risiede sull'array o sulla stringa stessa — risiede su Array.prototype o String.prototype e viene trovato percorrendo la catena dei prototipi.

Questa pagina spiega dove questi prototipi si collocano nella catena, come ispezionarli, come prendere in prestito i loro metodi per oggetti che non sono veri array, e perché estenderli in modo permanente è sconsigliato. Se sei nuovo al funzionamento della catena stessa, leggi prima ereditarietà prototipale.

Il Ruolo dei Prototipi Nativi

I prototipi nativi sono fondamentali in JavaScript: sono il motivo per cui ogni valore letterale viene precaricato con metodi utili senza che tu debba definire nulla. Capire come si inseriscono nella catena dei prototipi ti permette di comprendere i messaggi di errore, riutilizzare metodi predefiniti in contesti inaspettati ed evitare bug sottili.

Object.prototype: la Radice della Catena

Quasi ogni object che crei alla fine eredita da Object.prototype, che si trova in cima alla catena. È da lì che provengono metodi come toString, hasOwnProperty e valueOf. Quando una ricerca fallisce su un object e su ogni prototipo intermedio, la catena termina a Object.prototype e il collegamento successivo è null.

javascript— editable

Prototipi di Array, Function e Number

I tipi predefiniti aggiungono il proprio prototipo sopra Object.prototype. Un array, ad esempio, eredita da Array.prototype (che fornisce map, filter, push, …), e Array.prototype a sua volta eredita da Object.prototype. Lo stesso schema vale per le funzioni e i numeri.

javascript— editable

Prendere in Prestito Metodi con call e apply

Poiché i metodi nativi risiedono sui prototipi, puoi prenderli in prestito ed eseguirli su qualsiasi valore compatibile usando call o apply. L'esempio classico è usare i metodi di Array.prototype su oggetti simili agli array (come arguments o una string) che non possiedono tali metodi propri.

javascript— editable

Estendere i Prototipi Nativi

Sebbene JavaScript consenta di estendere i prototipi nativi, questa pratica è generalmente sconsigliata nello scope globale a causa di potenziali conflitti in codebase di grandi dimensioni o con script di terze parti. Ci sono diversi motivi concreti per evitarla:

  • Collisioni di nomi. Se due script aggiungono un metodo con lo stesso nome (o una versione futura di ECMAScript standardizza quel nome con un comportamento diverso), uno sovrascrive silenziosamente l'altro.
  • Enumerabilità. Un metodo aggiunto con una semplice assegnazione è enumerabile, quindi appare nei cicli for...in su ogni object di quel tipo, a meno che non sia protetto con hasOwnProperty — una fonte comune di bug.
  • Effetti collaterali globali. La modifica interessa ogni valore di quel tipo nell'intero programma, incluso il codice che non hai scritto tu.

Il frammento di seguito mostra il problema con for...in. Una normale assegnazione si propaga nel ciclo; usare Object.defineProperty per rendere il metodo non-enumerabile non lo fa.

javascript— editable

Comprendere questa funzionalità è comunque utile per riconoscere potenziali problemi, leggere polyfill ed esplorare pattern avanzati in ambienti controllati.

Esempi Pratici di Utilizzo dei Prototipi Nativi

Manipolare gli Array con Array.prototype

Considera la potenza di Array.prototype, che offre metodi come map, filter e reduce. Questi metodi forniscono soluzioni eleganti per trasformare e gestire i dati memorizzati negli array. Possiamo aggiungere nuovi metodi manipolando Array.prototype.


javascript— editable

In questo esempio, definiamo un nuovo metodo mapToSquare sul prototipo, che utilizza il metodo predefinito map per restituire il quadrato di ogni numero.

Arricchire le Stringhe con String.prototype

String.prototype è un altro ricco repository di metodi, come toLowerCase, toUpperCase e includes, che facilitano le operazioni di manipolazione e interrogazione delle string.


javascript— editable

In questo esempio, definiamo removeSpace sul prototipo, usando split, filter e join per rimuovere gli spazi.

Estensioni Personalizzate ai Prototipi Nativi

Sebbene sia necessaria cautela, l'aggiunta di metodi personalizzati ai prototipi nativi può dimostrare la flessibilità di JavaScript. Ecco come potresti estendere Array.prototype per includere un metodo che calcola la somma degli elementi di un array:


javascript— editable

Questo metodo personalizzato, sum, aggiunge una nuova dimensione al prototipo di Array, illustrando sia il potenziale che i rischi dell'estensione dei prototipi nativi.

Buone Pratiche per l'Utilizzo dei Prototipi Nativi

Sebbene la potenza dei prototipi nativi sia innegabile, ecco alcune buone pratiche per garantire che il codice rimanga robusto e privo di conflitti:

  • Evitare di Estendere i Prototipi Nativi: Se non è assolutamente necessario, evita di modificare i prototipi predefiniti per prevenire comportamenti inattesi nel tuo codice o nelle librerie di terze parti.
  • Usare Object.defineProperty per Estensioni Più Sicure: Quando devi aggiungere metodi, usa Object.defineProperty per renderli non-enumerabili. Questo impedisce ai cicli for...in di raccogliere le tue proprietà personalizzate e riduce i conflitti di denominazione.
  • Usare i Polyfill con Saggezza: Quando usi i polyfill per aggiungere funzionalità mancanti nei browser più vecchi, assicurati che verifichino l'esistenza del metodo prima di aggiungerlo al prototipo.
  • Sfruttare le Funzionalità Moderne di JavaScript: Con l'evoluzione di JavaScript, molte operazioni che un tempo richiedevano l'estensione dei prototipi nativi possono ora essere realizzate con nuovi costrutti del linguaggio, come classi e moduli.

Conclusione

I prototipi nativi sono il meccanismo alla base di ogni metodo predefinito che usi quotidianamente: si trovano nella catena dei prototipi, con Object.prototype alla radice, e permettono a valori come array, funzioni e numeri di condividere comportamenti. Sapere come ispezionarli con Object.getPrototypeOf, prendere in prestito i loro metodi con call e apply, e resistere alla tentazione di estenderli globalmente renderà il tuo codice più capace e più prevedibile.

Per approfondire, vedi ereditarietà prototipale per capire come viene costruita la catena, e metodi dei prototipi e oggetti senza __proto__ per la moderna API Object.create / Object.getPrototypeOf.

Esercitazione

Pratica
Cosa è vero riguardo all'estensione dei prototipi nativi in JavaScript?
Cosa è vero riguardo all'estensione dei prototipi nativi in JavaScript?
Was this page helpful?