Typeof em JavaScript é realmente muito complexo. Ele pode ser usado para fazer muitas coisas, mas também tem muitos comportamentos estranhos. Este artigo lista seus múltiplos usos e também aponta problemas e soluções existentes.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Ftypeof
> tipo de indefinido
'indefinido'
> typeof null // bug bem conhecido
'objeto'
> tipo de verdadeiro
'booleano'
>tipo de 123
'número'
> tipo de "abc"
'corda'
> tipo de função() {}
'função'
> tipo de {}
'objeto'
>tipo de[]
'objeto'
> tipo de variável desconhecida
'indefinido'
1. Verifique se uma variável existe e tem um valor.
typeof retornará "indefinido" em duas situações: quando uma variável não é declarada e quando o valor de uma variável é indefinido.
> tipo deVariável não declarada === "indefinido" verdadeiro > varVariável declarada > tipo deVariável declarada 'indefinido' > tipo de indefinido 'indefinido';
Existem outras maneiras de detectar se um valor é indefinido:
> var valor = indefinido; > valor === indefinido verdadeiro
Mas se este método for usado em uma variável não declarada, uma exceção será lançada, porque somente typeof pode detectar variáveis não declaradas normalmente sem reportar um erro:
> undeclaredVariable === indefinido ReferenceError: undeclaredVariable não está definido
Nota: Variáveis não inicializadas, parâmetros formais sem parâmetros passados e propriedades inexistentes não terão os problemas acima, pois estão sempre acessíveis e o valor é sempre indefinido:
> var declaradaVariável; > declaradaVariável === indefinido verdadeiro > (função (x) { return x === indefinido }()) verdadeiro > ({}).foo === indefinido verdadeiro
Nota do tradutor: portanto, se quiser detectar a existência de uma variável global que pode não ser declarada, você também pode usar if(window.maybeUndeclaredVariable){}
Problema: typeof é complicado para realizar tal tarefa.
Solução: Este tipo de operação não é muito comum, por isso algumas pessoas acham que não há necessidade de encontrar uma solução melhor. Mas talvez alguém proponha um operador especial:
> definida UndeclaredVariable falsa > var declaradaVariable > definida declaradaVariable falsa;
Ou talvez também seja necessário um operador que detecte se uma variável é declarada:
> declarou Variável não declarada falsa > var Variável declarada > declarou Variável declarada verdadeira;
Nota do tradutor: Em Perl, o operador definido acima é equivalente a definido(), e o operador declarado acima é equivalente a existe().
2. Determine se um valor não é igual a indefinido ou nulo.
Problema: Se você quiser verificar se um valor foi definido (o valor não é indefinido nem nulo), então você encontra uma das peculiaridades mais famosas de typeof (considerada um bug): typeof null retorna "objeto":
> tipo de null 'objeto'
Nota do tradutor: Isso só pode ser considerado um bug na implementação original do JavaScript, e é assim que o padrão V8 foi revisado e implementado, typeof null === "null", mas acabou se mostrando inviável. //wiki.ecmascript.org/doku.php?id=harmony:typeof_null
Solução: não use typeof para esta tarefa, use uma função como esta:
função isDefined(x) { return x !== null && x !== indefinido }
Outra possibilidade é introduzir um "operador de valor padrão", onde a seguinte expressão retorna defaultValue se myValue não estiver definido:
meuValor ?? valor padrão
A expressão acima é equivalente a:
(meuValor! == indefinido && meuValor! == nulo) ?
Ou:
meuValor ??= valorpadrão
Na verdade, é uma simplificação da seguinte afirmação:
meuValor = meuValor ??
Ao acessar uma propriedade aninhada, como bar, você pode precisar da ajuda deste operador:
obj.foo.bar
Se obj ou obj.foo for indefinido, a expressão acima lançará uma exceção. Um operador.?? permite que a expressão acima retorne o primeiro valor encontrado ao percorrer as propriedades camada por camada.
obj.??foo.??barra
A expressão acima é equivalente a:
(obj === indefinido || obj === nulo) ? obj: (obj.foo === indefinido || obj.foo === nulo) ?
3. Distinguir entre valores de objetos e valores primitivos
A função a seguir testa se x é um valor de objeto:
function isObject(x) { return (typeof x === "função" || (typeof x === "objeto" && x !== nulo));
Problema: A detecção acima é complicada porque typeof considera funções e objetos como tipos diferentes, e typeof null retorna "objeto".
Solução: O método a seguir também é frequentemente usado para detectar valores de objetos:
função isObject2(x) { return x === Objeto(x });
Aviso: você pode pensar que pode usar instanceof Object para detectar aqui, mas instanceof determina o relacionamento da instância usando o protótipo de um objeto, então e objetos sem protótipos:
> var obj = Object.create(null);
obj é de fato um objeto, mas não é uma instância de nenhum valor:
> typeof obj 'objeto' > obj instanceof Object falso
Na prática, você raramente encontrará tal objeto, mas ele existe e tem sua utilidade.
Nota do tradutor: Object.prototype é um objeto que existe por padrão e não possui protótipo.
>Object.getPrototypeOf(Object.prototype)null>typeof Object.prototype'object'>Object.prototype instanceof Object falso
4.Qual é o tipo de valor primitivo?
typeof é a melhor maneira de verificar o tipo de um valor primitivo.
> typeof "abc" 'string' > typeof indefinido 'indefinido'
Problema: você deve estar ciente do comportamento estranho de typeof null.
> typeof null // Cuidado! 'objeto'
Solução: A função a seguir pode corrigir esse problema (apenas para este caso de uso).
function getPrimitiveTypeName(x) { var typeName = typeof x; typeName) { case "indefinido": case "boolean": case "number": case "string": return typeName "objeto": if (x == = null) { return "null" } default: // Nenhum dos julgamentos anteriores foi aprovado throw new TypeError("O parâmetro não é um valor primitivo: "+x } }
Uma solução melhor: implemente uma função getTypeName(), que além de retornar o tipo do valor original, também pode retornar o atributo interno [[Class]] do valor do objeto. jQuery $.type é uma implementação desse tipo)
5. Se um determinado valor é uma função
typeof pode ser usado para detectar se um valor é uma função > typeof function () {} 'function' > typeof Object.prototype.toString 'function'.
Em princípio, instância A função também pode detectar esse requisito. À primeira vista, parece que o método de escrita é mais elegante. No entanto, o navegador tem uma peculiaridade: cada quadro e janela tem suas próprias variáveis globais. object for passado para outro framework, instanceof não funcionará corretamente porque os dois frameworks possuem construtores diferentes. É por isso que existe um método Array.isArray() no ECMAScript 5. Seria bom se houvesse um método cross-framework para verificar se um objeto é uma instância de um determinado construtor. O getTypeName() acima é uma solução alternativa disponível. , mas pode haver uma solução mais fundamental.
6.Visão geral
Os itens mencionados a seguir devem ser os recursos mais urgentemente necessários em JavaScript no momento e podem substituir alguns dos recursos funcionais das responsabilidades atuais de typeof:
isDefined() (como Object.isDefined()): pode ser usado como uma função ou um operador
isObject()
getTypeNome()
Um mecanismo de estrutura cruzada para detectar se um objeto é uma instância de um construtor especificado
A necessidade de verificar se uma variável foi declarada pode não exigir o seu próprio operador.