Cómo obtener el tipo de datos preciso de una variable en Javascript

Introducción

Una de las características del lenguaje Javascript más controvertidas es su tipado blando o dinámico del que ya hemos hablado em alguma ocasião. Isso significa que, ao contrário de outras linguagens clássicas, como C ou Java, quando declaramos variáveis, não precisamos especificar o tipo de dados que eles conterão. Além disso, a mesma variável pode possuir vários tipos diferentes em diferentes momentos de execução: pode começar a ser um todo, tornar-se uma matriz e, por exemplo, acabar sendo um objeto.

Essa flexibilidade Vantagens muito interessantes para o desenvolvimento de aplicações complexas, uma vez que não há limitações priori sobre o que uma variável pode armazenar. No entanto, para aqueles que vêm de outros idiomas com ponta dura, um dos problemas deste conceito é que é muito difícil identificar o tipo de dados específico que uma variável tem em um determinado momento de execução.

Identificando O tipo

efetivamente, o JavaScript não possui um meio univo para identificar o tipo de dados que contém uma variável em um determinado momento. Nativamente, temos duas instruções que podem nos dar um valor aproximado, mas que, infelizmente, não são finais: tipof e instanceof.

o operador tipo de

tipoof é um operador desdenhoso, o que o que significa que ele só aceita (e opera) em um único argumento; Neste caso, uma variável:

 typeof 2; // numptypeof 'Olá World' // StringTypeof // Objeto  Pré> 

Este operador não é uma função; No entanto, os parênteses podem ser usados para agrupar os termos a serem avaliados:

 TypeOf (2); // Nubertypeof ('Hello World'); // stringtypeof ('foo', 4); // Número  Pré> 

Nota: Agrupamentos de argumentos em JavaScript determinam o valor final de um elemento através do uso de operadores internos. Esses operadores indicam a ordem em que os termos são avaliados, como a vírgula, o que torna essa avaliação da esquerda para a direita para retornar o valor do segundo operando. Para obter mais informações sobre este aspecto do idioma, o item O operador de comta JavaScript é recomendado.

A tabela a seguir mostra a correspondência de objetos JavaScript e o valor obtido com o Typef:

Tipo indefinido “indefinido” null “objeto” booleano “booleano” número “number” string “string” objeto de host (dentro do JS Ambiente) depende da implementação objeto xml e4x “xml” xmllist e4x “xml” Qualquer outro objeto

Como podemos Vejo Não há referência na tabela antes de elementos como matrizes, datas, expressões regulares, etc … Isso significa que para o tipo de, esses elementos são mais um objeto. Além disso, vemos alguns resultados que podem parecer confusos como nulo em que recebemos como um tipo de novo ‘objeto’:

 typeof nan; // Nubertypeof infinito; // NubertypeOF (1/0); // Nubertypeof (Typef); // string 

Parece que não podemos confiar nesse operador demais para determinar o tipo de dados que avaliamos, por isso pode ser interessante procurar outro mais seguro ou completo solução.

object.prototype.String

A função de toString, retorna uma string que representa o objeto indicado como argumento:

 objeto.prototype.tring (); // 

Vamos ver o resultado: “”: De acordo com a especificação ECMAScript5, Object.prototype.String retorna como resultado a concatenação da cadeia “objeto” mais valor interno do objeto O que é passado (o que chamamos de classe – classe) …

]

Todos os objetos Javascript têm um proprietário interno conhecido como] (a notação com fecho duplo é o mesmo usado na especificação do ES5). De acordo com o ES5,] é uma corrente com um único valor (não editável) que identifica cada objeto. Assim, um objeto invocado com o construtor e que não foi modificado, retorna como valor dessa propriedade o tipo de objeto preciso ao qual ele pertence:

 var o = novo objeto (); ou.picar (); // 

No entanto, vemos que este operador também é frágil quando a aplicamos em objetos comuns:

 .tring (); // "foo, bar, 1" "Olá mundo" .tostring (); // "Olá mundo" /a-z/.testring (); // "/ a-z /" 

Isso é assim porque os objetos personalizados substituem o método Object.Prototype.String com o seu próprio. Uma maneira de resolver isso é invocar este método diretamente do objeto objeto e usar a função de chamada para injetar o argumento desejado:

 object.prothotype.tring.call (); // objeto.prototipo.Toscall ("Hello World"); // objeto.prototype.tring.call (/ a-z /); // 

Desta forma, evitamos sobrescrever qualquer coisa e o resultado obtido é esperado: temos o tipo correto de dados.

Criando uma função para Determine o tipo de dados

Extraído diretamente do artigo Angus Croll, podemos usar a seguinte função para obter o tipo correto de dados de uma variável ou objeto:

 vartype = function (obj) {retorno ({}). Tostring.call (obj) .Match (/ \ s (+) /) . TOLOWCASE ()} 

Vamos examiná-lo em partes:

  • ({}). A tostring é uma abreviatura (um atalho) de objeto .Prototipo. Toasring Desde então, em qualquer novo objeto, o método de toalstring refere-se à definição dada pelo objeto.Prototype como vimos acima.
  • chamar nós usá-lo aqui para que o método anterior seja feito no argumento que indicamos, neste caso, outro objeto.
  • jogo: usamos uma expressão regular para extrair o tipo de dados sem a caden No ‘objeto’ inicial e dos suportes. Usamos uma expressão regular em vez de uma fatia ou outro método devido ao melhor desempenho que oferece sobre o resto.
  • tolograma: passamos por minúsculo para diferenciar o tipo de qual seria a referência à instância de Um objeto e que, geralmente, é maiúsculo.
  • Vamos ver como a função se comporta:

     Totipo ({A: 4}); // "objeto" totype (); // "Array" (função () {console.log (totype (argumentos))); // ArgumentStoType (novo ReferenceError); // "erro" totype (nova data); // "Data" Totipo (/ a-z /); // "regexp" Totipo (matemática); // "matemática" toty (JSON); // "JSON" Totype (novo número (4)); // "Número" Totipo (nova string ("ABC"); // "string" toty (novo booleano (verdadeiro)); // "booleano" 

    e vamos compará-lo com o que obteríamos com o tipo de:

     typeof {a: 4}; // "objeto" tipof; // "Object" (função () {console.log (tipo de argumentos)} (); // ObjectTypeof New ReferenceError; // "Objeto" Typef New Date; // "Objeto" tipoof / a-z /; // "objeto" tipo de matemática; // "Objeto" tipo de JSON; // "objeto" tipo de novo número (4); // "Objeto" Typef New String ("ABC"); // "Objeto" tipo de novo booleano (verdadeiro); // "Object" 

    A diferença na maioria dos casos é importante: da imprecisão do tipo, fomos para obter tipos específicos.

    Comparação com a instância

    A instância do operador verifica a cadeia prototípica do primeiro operando buscando a presença da propriedade prototípica do segundo, que deverá corresponder a um construtor:

     nova data da data da data; // verdadeira instância de matriz; // true 

    o problema deste operador é que alguns objetos em javascript não têm um construtor associado para que eles não possam ser avaliados corretamente por instanceof:

     instance de matemática de matemática // tipoError 

    há também o problema desses ambientes com múltiplos quadros, onde a presença de vários contextos globais (um para cada quadro) evitam garantir que um determinado objeto seja uma instância de um determinado construtor:

     var iframe = document.createelement ('iframe'); documento.body.Appendchild (iframe); var iframearray = window.frames.array; var array = novo iframearray (); Instância da matriz de matriz; // faldesearray instanceof ifmeearray; // true; 

    limitações

    A função toty não pode ser evitada de erros contra tipos de dados desconhecidos:

     object.totype (FFF); // referenciador 

    Especificamente, é a chamada para Totipo que lança o erro, não a própria função. A única maneira de evitar que isso seja usando a comparação implícita que nos permite o sistema de curto-circuito de JavaScript:

     window.fff & & objeto.Totype (FFF); 

    Se a primeira condição for cumprida, a próxima é continuada; Caso contrário, o circuito é cortado e o erro é evitado.

    Conclusão

    em javacript, não podemos determinar com precisão o tipo de dados de uma variável usando os métodos nativos que fornece ao idioma em si. Normalmente, quando precisamos identificar tipos, geralmente recorremos a técnicas aproximadas, como a digitação de pato. No entanto, em aplicativos em que a integridade é crítica, essa técnica não permite que o rigor necessário.

    Tanto o tipo de e instanceof não ofereça controle rigoroso, confiável e univocal sobre os tipos que poderíamos precisar durante um desenvolvimento. Para tentar resolver essa falta, usamos algumas das peculiaridades da linguagem, como valor], para alcançar um resultado muito mais preciso.

    Este artigo é uma tradução expandida do original de Angus Cloll: Fixando o JavaScript TypeOf Operator.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *