Saber cuál es el tipo de un dato suele ser muy importante para que el código se ejecute sin problemas y sin errores.
JavaScript tiene varias formas de comprobar el tipo de un valor o de un objeto.
Los mecanismos de verificación de tipos de JavaScript pueden ser algo poco fiables.
Para lograr una mayor seguridad de tipos y tipos más robustos, probablemente deberías usar TypeScript, un lenguaje que se construye sobre JavaScript, pero con la sintaxis de tipos de un lenguaje de tipado estático.
typeof
El operador typeof devuelve el tipo de su operando.
El resultado es un string que coincide con el nombre de uno de los tipos de datos primitivos, excepto "null".
También puede ser "function" o "object".
typeof undefined;
// => "undefined"
typeof true;
// => "boolean"
typeof 42;
// => "number"
typeof 'Hello, World!';
// => "string"
typeof function () {
return 'Hello, World';
};
// => "function"
typeof [1, 2, 3, 4];
// => "object"
typeof { city: 'Stockholm', country: 'Sweden' };
// => "object"
Por [razones históricas][typeof null is "object"].
instanceof
Para comprobar el tipo de un objeto, puedes usar el operador instanceof.
Se evalúa a un boolean según si el segundo operando está incluido en la cadena de prototipos del primer operando.
Para aclararlo, instanceof devolverá si el primer operando es una instancia del segundo operando o de una de sus clases hijas.
instanceof solo funciona con objetos.
class Beverage {
// ...
}
// The Coffee class is a child of the Beverage class.
class Coffee extends Beverage {
// ...
}
const java = new Coffee();
java instanceof Coffee;
// => true
java instanceof Beverage;
// => true
La clase Array tiene un método llamado Array.isArray() que comprueba si su argumento es un array.
Si bien instanceof Array no funcionará con un array creado en un realm diferente, como un iframe en una página web, Array.isArray() sí lo hará.
Esto se debe a que la clase Array tiene un constructor diferente en cada realm, y cada iframe tiene su propio realm, lo que significa que la función en la cadena de prototipos será diferente, y eso hace que instanceof Array falle.
Array.isArray() es capaz de ignorar esto y siempre debería usarse cuando sea posible.
También sobrevive a los falsos positivos en los que un objeto en realidad no es un Array y solo tiene Array en su cadena de prototipos.
({ __proto__: Array.prototype }) instanceof Array
// => true
Array.isArray({ __proto__: Array.prototype })
// => false
in
El operador in devuelve si el primer operando es una propiedad del segundo operando.
No comprueba que la propiedad tenga un valor definido.
Una propiedad establecida en undefined seguirá siendo detectada por in.
class Coffee {
constructor() {
this.temperature = 'hot';
this.isDarkMatter = undefined;
}
coolDown() {
this.temperature = 'warm';
}
}
const espresso = new Coffee();
'temperature' in espresso;
// => true
'color' in espresso;
// => false
'isDarkMatter' in espresso;
// => true
in devolverá true para las propiedades y los métodos heredados.
"coolDown" in espresso
// => true
"constructor" in espresso
// => true
Para evitar esto, usa Object.hasOwn() en su lugar
Object.hasOwn()
El método Object.hasOwn() devuelve si el objeto especificado posee la propiedad dada (no es heredada ni es un método).
class Coffee {
constructor() {
this.temperature = 'hot';
}
coolDown() {
this.temperature = 'warm';
}
}
const cappuccino = new Coffee();
Object.hasOwn(cappucino, 'temperature');
// => true
Object.hasOwn(cappucino, 'constructor');
// => false
Object.hasOwn(cappucino, 'coolDown');
// => false