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:
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.