Javascript verifica o tipo de uma variável. Getter operador typeof

a = (b> 0) && (c + 1! = d); sinalizador =! (status = 0);

Tabela 14.5. Operadores lógicos

Descrição do operador

! NÃO (inversão lógica)

&& AND (multiplicação lógica)

|| OU (adição lógica)

Tabela 14.6. Resultados da execução de operadores AND e OR

Operando 1

Operando 2

Tabela 14.7. Resultados da declaração NOT

Obter operador typeof

Obter operador de tipo typeof retorna uma string que descreve o tipo de dados do operando. O operando cujo tipo você deseja saber é colocado após este operador e entre parênteses:

s = typeof ("str");

Como resultado desta expressão, a variável s conterá a string "string" denotando o tipo da string.

Todos os valores que o operador typeof pode retornar estão listados na tabela. 14,8.

Tabela 14.8. Valores retornados pelo operador typeof

Tipo de dados

String devolvida

Corda

Numérico

Tabela 14.8 (final)

Tipo de dados

String devolvida

Lógico

Compatibilidade e conversão de tipo de dados

Agora é a hora de considerar duas questões mais importantes: compatibilidade de tipo de dados e conversão de um tipo para outro.

O que acontece quando você soma dois números? Isso mesmo - mais um valor numérico. E se você adicionar um número e uma string? É difícil dizer ... Aqui o JavaScript se depara com o problema da incompatibilidade de tipos de dados e tenta compatibilizar esses tipos convertendo um deles em outro. Primeiro, ele tenta converter a string em um número e, se for bem-sucedido, faz a adição. Se malsucedido, o número será convertido em uma string e as duas strings resultantes serão concatenadas. Por exemplo, a execução do script da Web na Listagem 14.6 converte o valor de b em um tipo numérico quando adicionado a a; assim, a variável c conterá o valor 23.

Listagem 14.6

var a, b, c, d, e, f; a = 11;

b = "12"; c = a + b;

d = "JavaScript"; e = 2;

Mas, uma vez que o valor da variável d não pode ser convertido em um número, o valor de e será convertido em uma string, e o resultado - o valor de f - se tornará

Os valores booleanos são convertidos em valores numéricos ou de string, conforme apropriado. Verdadeiro será convertido para o número 1 ou a string "1", e falso será convertido para 0 ou "0". Por outro lado, o número 1 será convertido em verdadeiro e o número 0 será convertido em falso. Além disso, falso será convertido

os valores são nulos e indefinidos.

Parte III. Comportamento das páginas da web. Scripts da web

Pode-se ver que o JavaScript está lutando para executar corretamente até mesmo expressões escritas incorretamente. Às vezes funciona, mas na maioria das vezes nem tudo funciona como planejado e, no final, a execução do script da Web é interrompida devido à descoberta de um erro em um local completamente diferente, no operador absolutamente correto. Portanto, é melhor não permitir tais incidentes.

Prioridade do operador

A última questão que examinaremos aqui é a precedência do operador. Como lembramos, a precedência afeta a ordem em que as instruções são executadas em uma expressão.

Que haja a seguinte expressão:

Neste caso, primeiro o valor de c será adicionado ao valor da variável b, e depois será subtraído da soma 10. Os operadores desta expressão têm a mesma prioridade e, portanto, são executados estritamente da esquerda para a direita.

Agora, considere uma expressão como esta:

Aqui, primeiro, o valor de c será multiplicado por 10, e só então o valor b será adicionado ao produto resultante. O operador de multiplicação tem precedência sobre o operador de adição, portanto, a ordem estrita da esquerda para a direita ficará fora de ordem.

Os operadores de atribuição têm a precedência mais baixa. É por isso que a própria expressão é avaliada primeiro e, em seguida, seu resultado é atribuído a uma variável.

EM Em geral, o princípio básico de execução de todos os operadores é o seguinte: os operadores com prioridade mais alta são executados primeiro e só depois os operadores com prioridade mais baixa. Operadores com a mesma prioridade são executados na ordem em que aparecem (da esquerda para a direita).

EM aba. 14.9 lista todos os operadores que estudamos em ordem decrescente de prioridade.

Tabela 14.9. Precedência do operador (ordem decrescente)

Operadores

Descrição

++ - - ~! tipo de

Incremento, decremento, mudança de sinal, NOT lógico, inferência de tipo

Multiplicação, divisão, levando o restante

Adição e concatenação de strings, subtração

Operadores de comparação

E lógico

Capítulo 14. Introdução à Programação da Web. Linguagem JavaScript

Tabela 14.9 (final)

Operadores

Descrição

OR lógico

Operador condicional (veja abaixo)

= <оператор>=

Atribuição, simples e complexa

ATENÇÃO!

Lembre-se desta tabela. A ordem de execução incorreta da instrução pode levar a erros difíceis de detectar, nos quais uma expressão aparentemente absolutamente correta dá o resultado errado.

Mas e se precisarmos quebrar a ordem normal de execução das instruções? Vamos usar parênteses. Com esta notação, as instruções entre parênteses são executadas primeiro:

a = (b + c) * 10;

Aqui, a adição dos valores das variáveis ​​bec será realizada primeiro e, em seguida, a soma resultante será multiplicada por 10.

Os operadores entre parênteses também estão sujeitos à precedência. Portanto, vários parênteses aninhados são frequentemente usados:

a = ((b + c) * 10 - d) / 2 + 9;

Aqui, as instruções serão executadas na seguinte sequência:

1. Adições be c.

2. Multiplique o valor resultante por 10.

3. Subtraindo d do produto.

4. Dividindo a diferença por 2.

5. Adicione 9 ao quociente.

Se você remover os colchetes:

a = b + c * 10 - d / 2 + 9;

então a ordem de execução dos operadores será a seguinte:

1. Multiplicação de ce 10.

2. Dividindo d por 2.

3. Adição be produtos ce 10.

4. Subtração do quociente da divisão da soma resultante d por 2.

5. Adicionando 9 à diferença resultante.

O resultado é completamente diferente, não é?

  • Indefinido Indefinido"
  • Nulo: "objeto"
  • Boolean: "boolean"
  • Número: "número"
  • String: "string"
  • Função: "função"
  • Todo o resto: "objeto"

As seguintes notas devem ser adicionadas a esta tabela:

1. typeof null === "objeto".

Teoricamente, este é um ponto sutil. Em linguagens tipadas estaticamente, uma variável de tipo de objeto não pode conter um objeto (NULL, nil, ponteiro nulo).

Na prática, isso é inconveniente em JavaScript. Portanto, os desenvolvedores do ES 5.1 farão algo mais intuitivo: typeof null === "null".

Mas, uma vez que temos o ES3 até agora, não se engane, por exemplo, sobre isto:

/ * A função procura algum objeto e o retorna ou nulo se nada for encontrado * / function search () () var obj = search (); if (typeof obj === "objeto") (// realmente encontramos o objeto (FALHA) obj.method ();)

2. Não se esqueça dos objetos de invólucro (typeof new Number (5) === "objeto").

3. E não se esqueça do direito dos navegadores de fazerem qualquer coisa com os objetos hospedeiros.

Não se surpreenda que o Safari teimosamente pense que HTMLCollection é um tipo de função, e o IE antes da versão 9 mantinha nossa função alert () favorita como um objeto. Também o Chrome costumava pensar o RegExp como função, mas agora parece ter percebido e respondido a ele com um objeto.

para sequenciar ()

Tentar descobrir o tipo de um valor a partir do resultado de seu método toString () é inútil. Em todas as "classes", esse método é substituído pelo seu próprio.

O método é bom para exibir informações de depuração, mas o tipo de uma variável não pode ser determinado por ele.

Object.prototype.toString ()

Embora toString seja redefinido dentro de "classes" concretas, ainda temos sua implementação original de Object. Vamos tentar usá-lo:

console.log (Object .prototype .toString .call (value));

console.log (Object.prototype.toString.call (valor));


Clinton dilui esse fardo

Curiosamente, esse método funciona surpreendentemente bem.

Para tipos escalares, retorna ,,,.

O engraçado é que até mesmo o novo Número (5) no qual typeof falhou aqui retorna.

O método falha em nulo e indefinido. Navegadores diferentes retornam, às vezes esperados e às vezes em geral. No entanto, é fácil determinar o tipo desses dois valores sem ele.

A diversão começa quando chegamos aos objetos (aqueles com typeof === "objeto").

objetos embutidos funcionam, praticamente, com um estrondo:

  • {} —
  • Encontro -
  • Erro -
  • RegExp -

A única coisa que sai da lista de argumentos é isso, então.
Com os objetos hospedeiros, as coisas estão piorando novamente.

No IE, os objetos DOM começaram a se tornar objetos "normais" apenas a partir da 8ª versão, e não exatamente até o fim. Portanto, no IE 6-8, todos esses objetos (HTMLCOllection, DOMElement, TextNode e junto com o documento e a janela) são convertidos em simplesmente.

Em todos os outros navegadores (incluindo o IE9), você já pode fazer algo com o resultado de toString. Embora nem tudo seja fácil: HTMLCollection está lá, então. janela - então, então, então. Mas você já pode tentar tirar algo disso.

É mais difícil com DOMElement: ele é exibido como, - seu próprio formato para cada tag. Mas aqui, a temporada regular vai nos ajudar.

A história é quase a mesma com outros objetos de host (nos testes de localização e navegador). Em todos os lugares, exceto no IE, eles podem ser identificados por sua string.

Dos contras de usar Object.prototype.toString ():

1. Esta oportunidade não é santificada pelo padrão. E aqui devemos nos alegrar por tudo estar funcionando tão bem, e não lamentar por algumas falhas.

2. A determinação do tipo analisando a string retornada por um método que não é para determinar o tipo, e também é chamado em um objeto ao qual não pertence, deixa algum resíduo na alma.

3. No antigo IE, como você pode ver, os objetos de host normalmente não são identificados.

No entanto, é uma grande peça de trabalho quando usado em conjunto com outras ferramentas.


Construtores

E, finalmente, construtores. Quem melhor para falar sobre a "classe" de um objeto em JS senão seu construtor?

Nulo e indefinido não possuem objetos de invólucro nem construtores.

O resto dos tipos escalares têm wrappers, respectivamente, você pode obter um construtor:

(5) .construtor === Número; (Número .NaN) .construtor === Número; (verdadeiro) .constructor === Boolean; ("string") .constructor === String;

(5) .construtor === Número; (Número.NaN) .construtor === Número; (verdadeiro) .constructor === Booleano; ("string"). construtor === String;

Mas instanceof não funcionará aqui:

5 instanceof Number; // false Number .NaN instanceof Number; // false true instanceof Boolean; // false "string" instanceof String; // falso

5 instanceof Number; // false Number.NaN instanceof Number; // false true instanceof Boolean; // false "string" instanceof String; // falso

(instanceof funcionará para o sofredor novo Número (5))

Com funções (que também são objetos), instanceof passará:

console.log ((function () ()) instanceof Function); // true console.log ((function () ()) .constructor === Function); // verdadeiro

console.log ((function () ()) instanceof Function); // true console.log ((function () ()). constructor === Function); // verdadeiro

Todos os objetos de classes internas também são facilmente identificados por seus construtores: Array, Date, RegExp, Error.

Um problema surge aqui com argumentos, cujo construtor é Object.

E a segunda com o próprio Object, ou melhor, como se referir a ele um objeto criado através de um construtor customizado.

Apenas o objeto base pode ser definido desta forma:

obj instanceof Object;

Como uma das variantes da definição - para iterar sobre todos os outros tipos possíveis (Array, Error ...) e se nenhum deles corresponder - "objeto".

Construtores e objetos hospedeiros

Com os objetos hospedeiros, as coisas estão piorando.

Vamos começar com o fato de que o IE, até e incluindo a versão 7, não os considera objetos normais. Eles simplesmente não têm construtores e protótipos lá (em qualquer caso, o programador não pode alcançá-los).

Outros navegadores se saem melhor. Existem construtores e você pode usá-los para determinar a classe de valor. Apenas eles são chamados de maneiras diferentes em navegadores diferentes. Por exemplo, para HTMLCollection, o construtor será HTMLCollection ou NodeList, ou mesmo NodeListConstructor.

Você também deve definir um construtor base para DOMElement. Em FF, é, por exemplo, HTMLElement, do qual HTMLDivElement e outros já são herdados.

FireFox abaixo da versão 10 e Opera abaixo da versão 11 fazem uma brincadeira, onde o construtor da coleção é Object.

constructor.name

Os construtores também têm uma propriedade de nome que pode ser útil.

Ele contém o nome da função construtora, por exemplo (5) .constructor.name === "Número".

Mas:
1. No IE não é de todo, mesmo no 9º.
2. Os navegadores novamente esculpem tudo em objetos Host (e frequentemente eles não têm essa propriedade). No Opera, DOMElement tem um nome de construtor em geral Function.prototype.
3. argumentos é novamente "objeto".

conclusões

Nenhum dos métodos apresentados fornece uma definição de cem por cento do tipo / classe do valor em todos os navegadores. No entanto, juntos eles permitem que você faça isso.

Em um futuro próximo, tentarei coletar todos os dados em tabelas e dar um exemplo de função definidora.

JavaScript ou Js(abreviado) não é uma linguagem simples e os desenvolvedores novatos não aprendem imediatamente sobre ela. No início, eles aprendem o básico e tudo parece colorido e bonito. Indo um pouco mais fundo, aparecem arrays, objetos, callbacks e similares em JavaScript, que o cérebro frequentemente remove.

Em JavaScript, é importante verificar o tipo de variável corretamente. Digamos que você queira saber se uma variável é um array ou um objeto? Como verificar corretamente? Nesse caso específico, há truques durante a verificação e é disso que se trata esta entrada. Vamos começar imediatamente.

Verificar o tipo de uma variável

Por exemplo, você precisa verificar se uma variável é um objeto, array, string ou número. Você pode usar typeof para isso, mas nem sempre vai dar a verdade, e no exemplo abaixo vou mostrar o porquê.

Escrevi este exemplo para ilustrar por que typeof nem sempre é a escolha certa.

Var _comparison = (string: "string", int: 99, float: 13.555, objeto: (hello: "hello"), array: new Array (1, 2, 3)); // Retorna um array com chaves de objeto var _objKeys = Object.keys (_comparison); para (var i = 0; i<= _objKeys.length - 1; i++) { // выведем в консоль тип каждой переменной console.log(typeof _comparson[_objKeys[i]]); }

O resultado da execução do código:

Objeto de objeto de número de string

Certo? - Claro que não. Existem dois problemas. Cada um deles será descrito em detalhes e uma solução será proposta.

Primeiro problema: número flutuante, saída como número

Comparison.float não é um número e deve ser um número flutuante em vez de um número. Para corrigir isso, você pode criar uma função com validação como no código abaixo.

Var _floatNumber = 9,22; var _notFloatNumber = 9; console.log (isFloat (_floatNumber)); console.log (isFloat (_notFloatNumber)); console.log (isFloat ("")); função isFloat (n) (retornar Número (n) === n && n% 1! == 0;)

A função isFloat () verifica todos os valores para números de ponto flutuante. Primeiro, ele verifica se a variável é igual a n number (Number (n) === n) e se assim for, então outra verificação é feita para a divisão com resto, e se houver um resto, então um booleano ( verdadeiro ou falso) resultado (n% 1! == 0).

No exemplo acima, ele retorna verdadeiro, falso e falso... O primeiro significado é flutuador tipo, o segundo não é - este é um número comum e o último é apenas uma string vazia que não se encaixa nas regras.

Segundo problema: a matriz foi definida como um objeto

No primeiro exemplo, a matriz foi exibida como um objeto e isso não é muito bom, porque às vezes você precisa usar esse tipo específico e nada mais.

Existem várias maneiras de testar uma variável para um tipo de array.

Primeira opção (boa opção). Verificamos se os dados pertencem a um array usando instanceof ().

Dados Var = novo Array ("olá", "mundo"); var isArr = instância de dados do Array;

Segunda opção (boa opção). O método Array.isArray () retorna um valor booleano, que dependerá se a variável é uma matriz ou não ().

Dados Var = novo Array ("olá", "mundo"); var isArr = Array.isArray (dados);

A terceira opção (a melhor, mas a mais longa). Por conveniência, você pode tornar isso uma função. Usando Object, nós fazemos. Se o resultado de Object.prototype.toString.call (data) não for igual, a variável não é um array ().

Dados Var = novo Array ("olá", "mundo"); var isArr = Object.prototype.toString.call (data) == ""; console.log (isArr);

O último resultado como uma função de conveniência:

Função isArray (data) (return Object.prototype.toString.call (data) == "")

Agora você pode chamar a função isArray () e definir uma matriz ou outra coisa como um argumento e ver o resultado.

Posfácio

A gravação acabou sendo bem grande do que se pretendia originalmente. Mas estou feliz com isso, porque descreve de forma breve e clara as dificuldades em verificar variáveis ​​em JavaScript e como contorná-las.

Se você ainda tiver dúvidas, escreva-as abaixo nesta entrada. Eu ficarei feliz em ajudar.

Operador tipo de retorna uma string que indica o tipo do operando.

Sintaxe

O operando segue o operador typeof:

Tipo de operando

Parâmetros

operandoé uma expressão que representa um objeto ou primitivo cujo tipo deve ser retornado.

Descrição

A tabela a seguir lista os possíveis valores de retorno de typeof. Mais informações sobre tipos e primitivas estão na página.

Exemplos de

// Números typeof 37 === "número"; typeof 3,14 === "número"; typeof (42) === "número"; typeof Math.LN2 === "número"; typeof Infinity === "número"; typeof NaN === "número"; // embora seja "Não-Um-Número" typeof Number (1) === "número"; // nunca use esta entrada! // Strings typeof "" === "string"; typeof "bla" === "string"; typeof "1" === "string"; // observe que o número dentro da string ainda é do tipo string typeof (typeof 1) === "string"; // typeof sempre retornará uma string neste caso typeof String ("abc") === "string"; // nunca use esta entrada! // Booleanos typeof true === "boolean"; typeof false === "boolean"; typeof Boolean (true) === "boolean"; // nunca use esta entrada! // Símbolos typeof Symbol () === "symbol" typeof Symbol ("foo") === "symbol" typeof Symbol.iterator === "symbol" // Undefined typeof undefined === "undefined"; typeof declarouButUndefinedVariable === "undefined"; typeof undeclaredVariable === "undefined"; // Objetos typeof (a: 1) === "objeto"; // use Array.isArray ou Object.prototype.toString.call // para distinguir entre objetos regulares e matrizes typeof === "objeto"; typeof new Date () === "objeto"; // O que está abaixo leva a erros e problemas. Não use! typeof new Boolean (true) === "objeto"; typeof new Number (1) === "objeto"; typeof new String ("abc") === "objeto"; // Funções typeof function () () === "function"; tipo de classe C () === "função"; typeof Math.sin === "função";

nulo

// Isso foi definido desde o nascimento JavaScript typeof null === "object";

Na primeira implementação de JavaScript, os valores foram representados por um tipo de tag e par de valores. O tipo de tag para objetos era 0. null era representado como um ponteiro nulo (0x00 na maioria das plataformas). Portanto, o tipo de tag para nulo era zero, então o valor de retorno de typeof é falso. ()

Uma correção foi sugerida no ECMAScript (via desabilitar), mas foi rejeitada. Isso resultaria em typeof null === "null".

Usando o novo operador

// Todas as funções construtoras criadas com "novo" serão do tipo "objeto" var str = new String ("String"); var num = novo número (100); typeof str; // Retorna "objeto" typeof num; // Retorna "objeto" // Mas há uma exceção para o construtor Function var func = new Function (); typeof func; // Retorna "função"

Expressões regulares

Expressões regulares chamáveis ​​eram um complemento não padrão em alguns navegadores.

Typeof / s / === "função"; // Chrome 1-12 não compatível com ECMAScript 5.1 typeof / s / === "objeto"; // Compatível com Firefox 5+ ECMAScript 5.1

Erros relacionados a zonas mortas temporárias

Antes do ECMAScript 2015, era garantido que o operador typeof retornaria uma string para qualquer operando com o qual fosse chamado. Isso mudou com a adição de declarações let e const de não elevação com escopo de bloco. Agora, se as variáveis ​​são declaradas com let e const, e typeof é chamado para elas no bloco de declaração de variável, mas antes da declaração, um ReferenceError é lançado. O comportamento difere das variáveis ​​não declaradas, para as quais typeof retornará "indefinido". As variáveis ​​com escopo de bloco estão em uma "zona morta temporária" que dura desde o início do bloco até que a variável seja declarada. Nesta zona, uma tentativa de acessar variáveis ​​lança uma exceção.

Typeof undeclaredVariable === "undefined"; typeof newLetVariable; let newLetVariable; // ReferenceError typeof newConstVariable; const newConstVariable = "olá"; // ReferenceError

Exceções

Todos os navegadores atuais têm um objeto host document.all não padrão do tipo Undefined.

Typeof document.all === "undefined";

Embora a especificação permita nomes de tipo personalizados para objetos exóticos não padrão, é necessário que esses nomes sejam diferentes dos predefinidos. Uma situação em que document.all é indefinido deve ser considerada uma violação excepcional das regras.

Especificações (editar)

Especificação Status Comentários (1)
Rascunho mais recente do ECMAScript (ECMA-262)
Rascunho
ECMAScript 2015 (6ª edição, ECMA-262)
A definição de "The typeof Operator" nesta especificação.
Padrão
ECMAScript 5.1 (ECMA-262)
A definição de "The typeof Operator" nesta especificação.
Padrão
ECMAScript 3ª Edição (ECMA-262)
A definição de "The typeof Operator" nesta especificação.
Padrão
ECMAScript 1ª Edição (ECMA-262)
A definição de "The typeof Operator" nesta especificação.
Padrão Definição original. Implementado em JavaScript 1.1

Compatibilidade do navegador

Atualizar dados de compatibilidade no GitHub

ComputadoresMóvelServidor
cromadaBeiraRaposa de fogoInternet ExplorerÓperaSafáriAndroid webviewChrome para AndroidFirefox para AndroidOpera para AndroidSafari no iOSSamsung InternetNode.js
tipo decromada Apoio total 1 Beira Apoio total 12 Raposa de fogo Apoio total 1 IE Apoio total 3 Ópera Apoio total simSafári Apoio total simWebView Android Apoio total 1 Chrome Android Apoio total 18 Firefox Android Apoio total 4 Opera Android Apoio total simSafari iOS Apoio total simSamsung Internet Android Apoio total 1.0 nodejs Apoio total sim

Lenda

Apoio total Apoio total

Notas específicas do IE

No IE 6, 7 e 8, muitos objetos de host são objetos, mas não funções. Por exemplo.