Saber qual é o tipo de um dado é muitas vezes muito importante para que o código corra sem problemas e sem erros.
O Javascript tem várias formas de verificar o tipo de um valor ou de um objeto.
Os mecanismos de verificação de tipos do Javascript podem não ser muito fiáveis.
Para uma melhor segurança de tipos e tipos mais fortes, provavelmente deves usar TypeScript, uma linguagem que assenta no JavaScript, mas com a sintaxe de tipos de uma linguagem com tipos estáticos.
typeof
O operador typeof devolve o tipo do seu operando.
O resultado é uma string que corresponde ao nome de um dos tipos de dados primitivos, exceto "null".
Também pode ser "function" ou "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"
Isto deve-se a [razões históricas][typeof null is "object"].
instanceof
Para verificar o tipo de um objeto, podes usar o operador instanceof.
Avalia para um boolean consoante o segundo operando esteja ou não incluído na cadeia de protótipos do primeiro operando.
Para clarificar, o instanceof devolve se o primeiro operando é uma instância do segundo operando ou de uma das suas subclasses.
O instanceof só funciona com 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
A classe Array tem um método chamado Array.isArray() que verifica se o seu argumento é um array.
Enquanto o instanceof Array não funciona com um array criado noutro realm, como um iframe numa página web, o Array.isArray() funciona.
Isto acontece porque a classe Array tem um construtor diferente em cada realm, e cada iframe tem o seu próprio realm. Isso significa que a função na cadeia de protótipos será diferente, o que faz com que o instanceof Array falhe.
O Array.isArray() é capaz de ignorar isto e deve ser sempre usado quando possível.
Também sobrevive a falsos positivos, em que um objeto não é realmente um Array e tem apenas Array na sua cadeia de protótipos.
({ __proto__: Array.prototype }) instanceof Array
// => true
Array.isArray({ __proto__: Array.prototype })
// => false
in
O operador in devolve se o primeiro operando é uma propriedade do segundo operando.
Não verifica se a propriedade tem um valor definido.
Uma propriedade com o valor undefined continua a ser detetada pelo 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
O in devolve true para propriedades e métodos herdados.
"coolDown" in espresso
// => true
"constructor" in espresso
// => true
Para evitar isto, usa antes o Object.hasOwn()
Object.hasOwn()
O método Object.hasOwn() devolve se o objeto especificado possui a propriedade indicada (não é herdada nem é um 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