Javascript: identificare il tipo di un’oggetto
Spesso é necessario controllare se una variabile é di un certo tipo o di un’altro. Consideriamo questa funzione:
function media(a, b) {
return (a + b) / 2;
}
Se anche solo uno dei due argomenti, a
e b
, non fosse un numero, si verificherebbe un errore.
isNaN
La funzione isNaN
(is Not a Number, non é un numero) può essere utilizzata per capire se un oggetto sia un numero o meno.
Quindi, nel nostro esempio ossiamo evitare errori:
function media(a, b) {
if (isNaN(a) || isNaN(b)) {
return false;
}
return (a + b) / 2;
}
Tutto bene, quindi, per i numeri. E per altri oggetti?
L’operatore typeof
L’operatore typeof
é usato per rilevare il tipo primitivo di una variabile (i principali sono booleano, stringa, numero, indefinito, funzione).
Ecco alcuni esempi:
typeof 5 === 'number' // vero
typeof 3.14 === 'number // vero
typeof 'stringa!' === 'string' // vero
typeof '' === 'string' // vero
typeof true === 'boolean' // vero
typeof function() {} === 'function' // vero
typeof Object.toString === 'function' // vero
Ci sono però alcune situazioi in cui questo operatore ha un comportamento inaspettato:
typeof ['a', 'b', 7] === 'object' // vero: infatti, array non e' un tipo primitivo - gli array sono instance dell'oggetto Array
typeof null === 'object' // vero: questa e' una stranezza di JavaScript, nata per motivi storici.
typeof new String('stringa!') === 'object' // vero: causa confusione - non usare queste forme!
typeof new Number(3.14) === 'object' // come sopra
typeof new Boolean(true) === 'object' // come sopra
L’operatore instanceof
In genere, il metodo migliore é l’operatore instanceof
che, nella forma a instanceof b
, ritorna true
se a é instance di b, false
altrimenti.
A = function() {}
B = function() {}
ogg = new A();
ogg instanceof A // vero
ogg instanceof B // falso, perche' B non e' nella catena prototipale di ogg
ogg instanceof Object // vero, poiche':
A.prototype instanceof Object // vero, quindi Object e' nella catena prototipale di ogg
Riprendendo gli ultimi esempi dell’operatore typeof
:
['a', 'b', 7] instanceof Array // vero
new String('stringa!') instanceof String // vero
new Number(3.14) instanceof Number // vero
new Boolean(true) instanceof Boolean // vero
Purtroppo però neanche questo metodo é privo di ‘problemini’. Il più comune è che non funziona con Array provenienti da un’altro frame (ad es. da un’Iframe
).
Quindi, come creare una funzione che possa affidabilmente controllare se un’oggetto é un’Array o meno?
Una soluzione sorprendentemente semplice é il metodo toString
, che ci da il tipo dell’oggetto in forma di stringa:
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}