Come verificare se un oggetto possiede una proprietà in Javascript
Nelle lezioni precedenti abbiamo visto che gli oggetti Javascript sono aggregati o insiemi di proprietà. In questa lezione vediamo come sia possibile verificare la presenza o meno di una proprietà in un oggetto Javascript.
Operatore in
Verificare la presenza di una proprietà è spesso una necessità molto utile che si presenta nello sviluppo dei programmi.
Il metodo più semplice di verifica è utilizzare l'operatore in
. Vediamo un esempio:
1 2 3 4 5 6 7 8 9 10 |
|
in
prevede due operandi: una stringa che identifica la proprietà e l'oggetto in cui cercarla. Restituisce false
se la proprietà non è presente, mentre restituisce true
se essa è una proprietà dell'oggetto o di uno dei prototipi della sua catena.
Metodo hasOwnProperty
La seconda tecnica di verifica consiste nell'utilizzo del metodo hasOwnProperty
.
Questo metodo, in realtà, è un metodo dell'oggetto Object
e, pertanto, viene ereditato da quasi tutti gli oggetti (a meno che il loro prototipo non è null
). Infatti, come abbiamo visto nella lezione relativa alla creazione degli oggetti, quasi tutti gli oggetti hanno come prototipo l'oggetto Object
.
Attraverso questo metodo, che richiede come parametro una stringa contenente il nome della proprietà da ricercare, è possibile verificare la presenza o l'assenza di una proprietà. La differenza rispetto all'operatore in
, tuttavia, è che questo metodo restituisce true
solo per le own properties (come era intuibile dal nome). Vediamo, infatti, l'esempio:
1 2 3 4 5 6 7 8 9 10 |
|
Metodo propertyIsEnumerable
Analogamente al metodo hasOwnProperty
esiste anche il metodo propertyIsEnumerable
che viene ereditato sempre da Object
. Il suo funzionamento è identico a hasOwnProperty
, l'unica differenza consiste nel fatto che restituisce false se la own property non è enumerable
. Per capire cosa sia una proprietà numerabile o enumerable
rimandiamo alla prossima lezione. In generale tutte le proprietà sono enumerabili a meno che non si utilizzino le metaclassi, ma questo è un argomento delle prossime lezioni. Per questo motivo, per il momento, possiamo considerare i due metodi, hasOwnProperty
e propertyIsEnumerable
, sostanzialmente identici.
Accesso diretto
La tecnica finale per verificare l'esistenza o meno di una proprietà è il semplice accesso diretto. Anzichè richiederne l'esistenza, si può richiedere direttamente la proprietà e verificare che essa sia diversa da undefined
. Vediamo un esempio:
1 2 3 4 5 6 7 8 9 10 |
|
Vi è una sottile differenza tra questa tecnica e l'operatore in
. Utilizzando l'operatore in
è in grado di distinguere tra l'esistenza di una proprietà che è stata impostata a undefined
ed una proprietà che non esiste. Vediamo l'esempio:
1 2 3 4 5 6 7 8 |
|
Errori di accesso alle proprietà
In generale, accedere ad una proprietà di un oggetto che non esiste (come abbiamo fatto sopra) non è un errore:
1 2 3 4 5 6 |
|
Nell'esempio di sopra, la variabile result
varrà undefined
in quanto abbiamo provato ad accedere alla proprietà y
di A
, ma questa proprietà non esiste. L'interprete non lancerà eccezioni ma, anzi, l'esecuzione proseguirà come se nulla fosse accaduto.
Anche se a prima vista questo comportamento dell'interprete sembra strano o contraddittorio (in altri linguaggi verrebbe generata un'eccezione), esso è voluto. Ricordiamo, infatti, che gli oggetti in Javascript sono dinamici. Le proprietà possono essere aggiunge, rimosse e modificate a runtime. Pertanto, inserire un meccanismo di controllo che, ad ogni accesso in lettura, verifica l'esistenza o meno di una proprietà rallenterebbe in maniera considerevole l'esecuzione. Per questo motivo, i progettisti dello standard Javascript hanno optato per questo comportamento.
Ovviamente bisogna fare attenzione. Infatti, nel caso di sopra, non si presentano particolari problemi. Ma se la proprietà dell'oggetto fosse a sua volta un oggetto? Proviamo con un esempio:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
In questo esempio abbiamo l'oggetto composto A
di cui richiediamo la proprietà y
per poi richiedere la proprietà z
. Poiché effettivamente A
possiede una proprietà y
nessuna eccezione viene lanciata. Nel caso di B
, invece, dato che richiederne la proprietà y
restituisce undefined
, nel momento in cui richiediamo z
un'eccezione viene lanciata. Infatti è un errore in Javascript richiedere una proprietà di undefined
.
Potremmo risolvere il problema in questo modo:
1 2 3 4 |
|
Tuttavia è una soluzione prolissa e prona agli errori. Un modo più semplice per risolvere il problema è scrivere la seguente riga:
let result2 = B.y && B.y.z;
A prima vista, questa riga di codice può sembrare criptica. Ma ricordando come funzionano gli operatori booleani in Javascript, si può capire perché funziona. Infatti:
- Gli operatori booleani in Javascript sono cortocircuitati. Ciò significa che in questo caso in cui abbiamo l'operatore
&&
(and) se il primo operando è falso, l'interprete non valuterà il secondo in quanto è inutile. Per questo seB.y
èundefined
(che in Javascript è assimilabile afalse
), il secondo operandoB.y.z
non verrà valutato e non verrà generata un'eccezione. Inoltre, dato che in Javascript qualsiasi valore può essere considerato un booleano, quando l'operatore di sinistra di&&
è assimilabile afalse
, ne verrà restituito il risultato che, nel nostro caso, èundefined
. - Viceversa, se il primo operando è assimilabile a
true
, come ad esempio seB
avesse effettivamente una proprietày
, allora, in tal caso, verrebbe valutato il secondo operando e restituito il risultato. Per cui, seB.y.z
fosseundefined
otterremmo undefined, mentre se fosse diverso ne otterremmo il valore.
ECMAScript 2020 introduce un nuovo operatore: ?.
che prende il nome di operatore di accesso condizionale. Utilizzando tale operatore possiamo riscrivere la riga di sopra, in maniera ancora più sintetica, come:
let result2 = B?.y?.z;
Riassumendo
In questa lezione abbiamo visto come verificare l'esistenza di una proprietà di un oggetto attraverso l'operatore in
e i due metodi hasOwnProperty
e propertyIsEnumerable
. Inoltre abbiamo visto come, attraverso l'accesso diretto, sia possibile effettuare questa verifica. Sempre nel caso dell'accesso diretto abbiamo visto come usare gli operatori booleani cortocircuitati e l'operatore di accesso condizionale.
Nella prossima lezione vedremo il concetto di proprietà enumerabili e come enumerare o elencare tutte le proprietà di un oggetto.