Qual é a melhor maneira de verificar se uma propriedade de objeto em JavaScript é undefined
?
fonte
Qual é a melhor maneira de verificar se uma propriedade de objeto em JavaScript é undefined
?
A maneira usual de verificar se o valor de uma propriedade é o valor especial undefined
é:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
Para verificar se um objeto realmente não tem essa propriedade e, portanto, retornará undefined
por padrão quando você tentar acessá-lo:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
Para verificar se o valor associado a um identificador é o valor especial undefined
, ou se esse identificador não foi declarado. Nota: este método é a única maneira de se referir a um identificador não declarado (nota: diferente de ter um valor de undefined
) sem um erro precoce:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
Nas versões do JavaScript anteriores ao ECMAScript 5, a propriedade denominada "undefined" no objeto global era gravável e, portanto, uma verificação simples foo === undefined
pode se comportar inesperadamente se ela tiver sido redefinida acidentalmente. No JavaScript moderno, a propriedade é somente leitura.
No entanto, no JavaScript moderno, "undefined" não é uma palavra-chave e, portanto, variáveis dentro de funções podem ser nomeadas "undefined" e sombrear a propriedade global.
Se você estiver preocupado com esse caso improvável (edge), poderá usar o operador void para obter o undefined
próprio valor especial :
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
obj !== undefined
agora.undefined
costumava ser mutável, comoundefined = 1234
o que causaria resultados interessantes. Mas depois do Ecmascript 5, ele não pode mais ser gravado, para que possamos usar a versão mais simples. codereadability.com/how-to-check-for-undefined-in-javascriptAcredito que haja várias respostas incorretas para esse tópico. Ao contrário do que se pensa, "indefinido" não é uma palavra-chave em JavaScript e pode de fato ter um valor atribuído a ela.
Código correto
A maneira mais robusta de executar este teste é:
Isso sempre retornará o resultado correto e até lida com a situação em que
myVar
não é declarado.Código degenerado. NÃO USE.
Além disso,
myVar === undefined
haverá um erro na situação em que myVar não for declarado.fonte
=== undefined
desconcertante. Sim, você pode atribuir aundefined
, mas não há motivo legítimo para fazê-lo, e é previsível que isso possa danificar seu código. Em C você pode#define true false
, e em Python você pode atribuir aTrue
eFalse
, mas as pessoas não sentem a necessidade de projetar seu código nessas línguas, de tal forma a proteger contra a possibilidade de eles próprios deliberadamente sabotando seu próprio ambiente em outras partes do código . Por que a possibilidade de atribuirundefined
até vale a pena considerar aqui?void 0
obter o valor queundefined
aponta para. Então você pode fazerif (myVar === void 0)
. o0
não é especial, você pode literalmente colocar qualquer expressão lá.undefined
. MDN: undefinedApesar de ser veementemente recomendado por muitas outras respostas aqui,
typeof
é uma má escolha . Ele nunca deve ser usado para verificar se as variáveis têm o valorundefined
, porque atua como uma verificação combinada do valorundefined
e da existência de uma variável. Na grande maioria dos casos, você sabe quando existe uma variável etypeof
apenas apresentará o potencial para uma falha silenciosa se você digitar um erro de digitação no nome da variável ou na string literal'undefined'
.Portanto, a menos que você esteja realizando a detecção de recursos², onde há incerteza quanto ao escopo de um determinado nome (como verificar
typeof module !== 'undefined'
uma etapa no código específico de um ambiente CommonJS),typeof
é uma escolha prejudicial quando usada em uma variável, e a opção correta é para comparar o valor diretamente:Alguns equívocos comuns sobre isso incluem:
que a leitura de uma variável "não inicializada" (
var foo
) ou de um parâmetro (function bar(foo) { … }
chamado comobar()
) falhará. Isso simplesmente não é verdade - variáveis sem inicialização explícita e parâmetros que não receberam valores sempre se tornamundefined
e estão sempre no escopo.que
undefined
pode ser substituído. Há muito mais nisso.undefined
não é uma palavra-chave em JavaScript. Em vez disso, é uma propriedade no objeto global com o valor Indefinido. No entanto, desde ES5, essa propriedade é somente leitura e não configurável . Nenhum navegador moderno permitirá que aundefined
propriedade seja alterada e, a partir de 2017, esse é o caso há muito tempo. A falta de modo estrito também não afetaundefined
o comportamento - apenas faz declarações comoundefined = 5
não fazer nada em vez de jogar. Como não é uma palavra-chave, você pode declarar variáveis com o nomeundefined
, e essas variáveis podem ser alteradas, criando esse padrão outrora comum:mais perigoso do que usar o global
undefined
. Se você precisar ser compatível com ES3, substituaundefined
porvoid 0
- não usetypeof
. (void
sempre foi um operador unário que avalia o valor Indefinido para qualquer operando.)Com como as variáveis funcionam fora do caminho, é hora de abordar a questão real: propriedades do objeto. Não há motivo para nunca usar
typeof
para propriedades de objetos. A exceção anterior referente à detecção de recursos não se aplica aqui -typeof
possui apenas comportamento especial em variáveis e expressões que referenciam propriedades de objetos não são variáveis.Este:
é sempre exatamente equivalente a este³:
e levando em consideração o conselho acima, para evitar confundir os leitores sobre o motivo pelo qual você está usando
typeof
, porque faz mais sentido usar===
para verificar a igualdade, porque pode ser refatorado para verificar o valor de uma variável mais tarde e simplesmente parece melhor, você sempre deve usar=== undefined
³ aqui também .Outra coisa a considerar quando se trata de propriedades do objeto é se você realmente deseja verificar
undefined
. Um determinado nome de propriedade pode estar ausente em um objeto (produzindo o valorundefined
quando lido), presente no próprio objeto com o valorundefined
, presente no protótipo do objeto com o valorundefined
ou presente em qualquer um que não tenhaundefined
valor.'key' in obj
informará se uma chave está em algum lugar da cadeia de protótipos de um objeto eObject.prototype.hasOwnProperty.call(obj, 'key')
informará se está diretamente no objeto. Porém, não vou entrar em detalhes nesta resposta sobre protótipos e no uso de objetos como mapas com chave de cadeia, porque o objetivo principal é combater todos os maus conselhos em outras respostas, independentemente das possíveis interpretações da pergunta original. Leia sobreprotótipos de objetos no MDN para mais!¹ escolha incomum do exemplo do nome da variável? esse é um código morto real da extensão NoScript para Firefox.
² não assuma que não saber o que está no escopo é bom, em geral. vulnerabilidade de bônus causada por abuso de escopo dinâmico: Projeto Zero 1225
³ mais uma vez assumindo um ambiente ES5 + e que
undefined
se refere àundefined
propriedade do objeto global. substituir devoid 0
outra forma.fonte
undefined
, ocultando o contexto padrão. Que, para fins mais práticos, tem o mesmo efeito que sobrescrevê-lo.void 0
comparar com o indefinido, mas novamente - isso é bobagem e exagero.typeof something === "undefined")
no código.void 0
é (pela primeira vez) mais curto e mais seguro! Isso é uma vitória no meu livro.No JavaScript, há nulo e indefinido . Eles têm significados diferentes.
Marijn Haverbeke declara, em seu livro on-line gratuito " JavaScript eloquente " (grifo meu):
Então, acho que a melhor maneira de verificar se algo estava indefinido seria:
Espero que isto ajude!
Editar: em resposta à sua edição, as propriedades do objeto devem funcionar da mesma maneira.
fonte
undefined
é apenas uma variável que pode ser reatribuída pelo usuário: a gravaçãoundefined = 'a';
fará com que seu código não faça mais o que você pensa. Usartypeof
é melhor e também funciona para variáveis (não apenas propriedades) que não foram declaradas.O que isso significa: "propriedade de objeto indefinida" ?
Na verdade, pode significar duas coisas bem diferentes! Primeiro, pode significar a propriedade que nunca foi definida no objeto e, segundo, pode significar a propriedade que possui um valor indefinido . Vamos olhar para este código:
Está
o.a
indefinido? Sim! Seu valor é indefinido. Estáo.b
indefinido? Certo! Não existe nenhuma propriedade 'b'! OK, veja agora como diferentes abordagens se comportam nas duas situações:Podemos ver claramente isso
typeof obj.prop == 'undefined'
eobj.prop === undefined
são equivalentes, e eles não distinguem essas diferentes situações. E'prop' in obj
pode detectar a situação quando uma propriedade ainda não foi definida e não presta atenção ao valor da propriedade que pode ser indefinido.Então o que fazer?
1) Você deseja saber se uma propriedade é indefinida pelo primeiro ou pelo segundo significado (a situação mais típica).
2) Você quer apenas saber se o objeto tem alguma propriedade e não se importa com o seu valor.
Notas:
x.a === undefined
ou issotypeof x.a == 'undefined'
aumentaReferenceError: x is not defined
se x não estiver definido.undefined
é uma variável global (na verdade, ela estáwindow.undefined
nos navegadores). É suportado desde o ECMAScript 1st Edition e, desde o ECMAScript 5, é somente leitura . Portanto, em navegadores modernos, não pode ser redefinido para verdadeiro, como muitos autores adoram nos assustar, mas isso ainda é válido para navegadores mais antigos.Luta final:
obj.prop === undefined
vstypeof obj.prop == 'undefined'
Vantagens de
obj.prop === undefined
:undefined
Desvantagens de
obj.prop === undefined
:undefined
pode ser substituído em navegadores antigosVantagens de
typeof obj.prop == 'undefined'
:Desvantagens de
typeof obj.prop == 'undefined'
:'undefned'
( erro de ortografia ) aqui é apenas uma constante de cadeia de caracteres, portanto, o mecanismo JavaScript não pode ajudá-lo se você o tiver digitado incorretamente, como eu acabei de fazer.Atualização (para JavaScript do servidor):
O Node.js suporta a variável global
undefined
comoglobal.undefined
(também pode ser usada sem o prefixo 'global'). Não conheço outras implementações de JavaScript do lado do servidor.fonte
undefined
como membroglobal
. Também nemconsole.log(global);
nemfor (var key in global) { ... }
não aparece indefinido como membro do global . Mas teste como'undefined' in global
mostre o oposto.[[Enumerable]]
é falsa :-)Minuses of typeof obj.prop == 'undefined'
isso, isso pode ser evitado escrevendo comotypeof obj.prop == typeof undefined
. Isso também fornece uma simetria muito agradável.obj.prop === undefined
.if ('foo' in o
)… sua resposta é realmente a primeira resposta correta aqui. Quase todo mundo apenas responde essa frase.O problema se resume a três casos:
undefined
.undefined
.Isso nos diz algo que considero importante:
Há uma diferença entre um membro indefinido e um membro definido com um valor indefinido.
Mas infelizmente
typeof obj.foo
não nos diz qual dos três casos que temos. No entanto, podemos combinar isso com"foo" in obj
para distinguir os casos.Vale ressaltar que esses testes também são iguais para as
null
entradasEu diria que, em alguns casos, faz mais sentido (e é mais claro) verificar se a propriedade existe, do que verificar se está indefinida, e o único caso em que essa verificação será diferente é o caso 2, o raro caso de uma entrada real no objeto com um valor indefinido.
Por exemplo: Acabei de refatorar um monte de código que tinha um monte de verificações se um objeto tinha uma determinada propriedade.
O que ficou mais claro quando escrito sem um cheque por indefinido.
Mas, como já foi mencionado, estes não são exatamente os mesmos (mas são mais do que suficientes para minhas necessidades).
fonte
if (!("x" in blob)) {}
entre parênteses, porque o! O operador tem precedência sobre 'in'. Espero que ajude alguém.a = {b: undefined}
; entãotypeof a.b === typeof a.c === 'undefined'
mas'b' in a
e!('c' in a)
.{ x : undefined }
ou, pelo menos, adicioná-lo como outra alternativa a (2.) na tabela - tive que pensar por um momento para perceber que o ponto (2.) avaliaundefined
(embora você mencionou isso mais tarde).Isso funcionou para mim, enquanto os outros não.
fonte
typeof (something == "undefined")
.(typeof something) === "undefined"
.Não tenho certeza de onde a origem de usar
===
comtypeof
veio, e como uma convenção que eu vê-lo usado em muitas bibliotecas, mas o operador typeof retorna um literal de cadeia, e sabemos que frente-se, então por que você também quiser tipo verificá-lo também?fonte
==
ainda requer pelo menos uma verificação de tipo - o intérprete não pode comparar os dois operandos sem conhecer seu tipo primeiro.==
é menos um personagem que===
:)Como cruzar minha resposta de uma pergunta relacionada Como verificar se há "indefinido" em JavaScript?
Específico para esta pergunta, consulte casos de teste com
someObject.<whatever>
.Alguns cenários ilustrando os resultados das várias respostas: http://jsfiddle.net/drzaus/UVjM4/
(Observe que o uso de
var
parain
testes faz diferença quando em um invólucro com escopo definido)Código de referência:
E resultados:
fonte
Se você fizer
falhará quando a variável
myvar
não existir, porque myvar não está definido; portanto, o script está quebrado e o teste não tem efeito.Como o objeto da janela possui um escopo global (objeto padrão) fora de uma função, uma declaração será 'anexada' ao objeto da janela.
Por exemplo:
A variável global myvar é igual a window.myvar ou window ['myvar']
Para evitar erros ao testar quando existe uma variável global, é melhor usar:
A pergunta se uma variável realmente existe não importa, seu valor está incorreto. Caso contrário, é bobagem inicializar variáveis com indefinidas e é melhor usar o valor false para inicializar. Quando você souber que todas as variáveis declaradas foram inicializadas com false, basta verificar seu tipo ou confiar
!window.myvar
para verificar se ele possui um valor apropriado / válido. Portanto, mesmo quando a variável não está definida,!window.myvar
é a mesma paramyvar = undefined
ormyvar = false
oumyvar = 0
.Quando você espera um tipo específico, teste o tipo da variável. Para acelerar o teste de uma condição, é melhor:
Quando a primeira e simples condição for verdadeira, o intérprete pula os próximos testes.
É sempre melhor usar a instância / objeto da variável para verificar se ela obteve um valor válido. É mais estável e é uma maneira melhor de programação.
y)
fonte
Não vi (espero não ter perdido) ninguém verificando o objeto antes da propriedade. Portanto, este é o mais curto e mais eficaz (embora não necessariamente o mais claro):
Se o obj ou obj.prop for indefinido, nulo ou "falso", a instrução if não executará o bloco de código. Geralmente, esse é o comportamento desejado na maioria das instruções de bloco de código (em JavaScript).
fonte
var x = obj && obj.prop || 'default';
No artigo Explorando o abismo de nulo e indefinido em JavaScript , li que estruturas como Underscore.js usam esta função:
fonte
void 0
é apenas uma maneira curta de escreverundefined
(já que é o que o nulo seguido por qualquer expressão retorna), ele salva 3 caracteres. Também poderia funcionarvar a; return obj === a;
, mas esse é mais um personagem. :-)void
é uma palavra reservada, enquanto queundefined
não é ie, enquantoundefined
é igualvoid 0
por padrão, você pode atribuir um valor aundefined
egundefined = 1234
.isUndefined(obj)
: 16 caracteres.obj === void 0
: 14 caracteres. disse quase.Simplesmente qualquer coisa não está definida em JavaScript, é indefinida , não importa se é uma propriedade dentro de um Object / Array ou apenas como uma variável simples ...
O JavaScript
typeof
facilita a detecção de uma variável indefinida.Basta verificar se
typeof whatever === 'undefined'
e ele retornará um booleano.É assim que a famosa função
isUndefined()
no AngularJs v.1x é escrita:Portanto, como você vê a função receber um valor, se esse valor for definido, ele retornará
false
, caso contrário, para valores indefinidos, retornarátrue
.Então, vamos dar uma olhada nos resultados quando passarmos valores, incluindo propriedades de objetos, como abaixo, esta é a lista de variáveis que temos:
e verificamos como abaixo, você pode ver os resultados na frente deles como um comentário:
Como você vê, podemos verificar qualquer coisa usando algo parecido com isto em nosso código, como mencionado, você pode simplesmente usar
typeof
em seu código, mas se você o estiver usando repetidamente, crie uma função como a amostra angular que eu compartilho e continuo reutilizando como seguindo o padrão de código DRY.Além disso, mais uma coisa: para verificar a propriedade de um objeto em um aplicativo real que você não tem certeza, mesmo que o objeto exista ou não, verifique se o objeto existe primeiro.
Se você marcar uma propriedade em um objeto e o objeto não existir, lançará um erro e interromperá a execução de todo o aplicativo.
Tão simples que você pode envolver dentro de uma declaração if como abaixo:
Qual também igual a isDefined no Angular 1.x ...
Outras estruturas javascript, como o sublinhado, também possuem verificação de definição semelhante, mas eu recomendo que você use
typeof
se você já não estiver usando nenhuma estrutura.Também adiciono esta seção do MDN, que possui informações úteis sobre typeof, undefined e void (0).
mais> aqui
fonte
' if (window.x) {} ' é seguro contra erros
Provavelmente você quer
if (window.x)
. Essa verificação é segura mesmo que x não tenha sido declarado (var x;
) - o navegador não gera um erro.Exemplo: quero saber se meu navegador suporta a API do histórico
Como isso funciona:
window é um objeto que mantém todas as variáveis globais como seus membros e é legal tentar acessar um membro não existente. Se x não foi declarado ou não foi definido,
window.x
retornará indefinido . undefined leva a false quando if () avalia.fonte
typeof history != 'undefined'
realmente funciona nos dois sistemas.Ao ler isso, estou surpreso por não ter visto isso. Eu encontrei vários algoritmos que funcionariam para isso.
Nunca definido
Se o valor de um objeto nunca foi definido, isso impedirá o retorno
true
se for definido comonull
ouundefined
. Isso é útil se você deseja que true seja retornado para valores definidos comoundefined
Definido como indefinido ou nunca definido
Se você deseja que resulte como
true
para valores definidos com o valor deundefined
, ou nunca definidos, você pode simplesmente usar=== undefined
Definido como um valor falso, indefinido, nulo ou nunca definido.
Geralmente, as pessoas me pedem um algoritmo para descobrir se um valor é falso
undefined
, ounull
. Os seguintes trabalhos.fonte
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
->true
. Como isso é "nunca definido comoundefined
"? Isto está errado.fonte
Compare com
void 0
, por concisão.Não é tão detalhado quanto
if (typeof foo !== 'undefined')
fonte
foo
não for declarado.A solução está incorreta. Em JavaScript,
retornará true, porque ambos são "convertidos" para um booleano e são falsos. A maneira correta seria verificar
que é o operador de identidade ...
fonte
===
digite tipo igualdade + (igualdade primitiva | identidade do objeto), em que os primitivos incluem cadeias. Acho que a maioria das pessoas considera'abab'.slice(0,2) === 'abab'.slice(2)
não intuitivo se considerarmos===
o operador de identidade.Você pode obter uma matriz toda indefinida com o caminho usando o código a seguir.
jsFiddle link
fonte
getUndefiend
deveriagetUndefined
.Aqui está a minha situação:
Estou usando o resultado de uma chamada REST. O resultado deve ser analisado do JSON para um objeto JavaScript.
Há um erro que preciso defender. Se os argumentos à chamada restante estavam incorretos, na medida em que o usuário especificou os argumentos incorretos, a chamada restante volta basicamente vazia.
Ao usar este post para me ajudar a me defender, tentei isso.
Para minha situação, se restResult.data [0] === "objeto", então posso começar a inspecionar com segurança o restante dos membros. Se indefinido, jogue o erro como acima.
O que estou dizendo é que, para minha situação, todas as sugestões acima neste post não funcionaram. Não estou dizendo que estou certo e todo mundo está errado. Eu não sou um mestre de JavaScript, mas espero que isso ajude alguém.
fonte
typeof
guarda não se protege contra nada que uma comparação direta não possa suportar. SerestResult
for indefinido ou não declarado, ainda será lançado.if(!restResult.data.length) { throw "Some error"; }
Existe uma maneira agradável e elegante de atribuir uma propriedade definida a uma nova variável, se ela estiver definida, ou atribuir um valor padrão a ela como substituto, se não for definido.
É adequado se você tiver uma função que receba uma propriedade de configuração adicional:
Agora executando
fonte
Todas as respostas estão incompletas. Esta é a maneira correta de saber que existe uma propriedade 'definida como indefinida':
Exemplo:
Pena que esta foi a resposta certa, está enterrada em respostas erradas> _ <
Então, para quem passa, eu te darei indefinidos de graça !!
fonte
Analisando os comentários, para quem deseja verificar os dois é indefinido ou seu valor é nulo:
Se você estiver usando a biblioteca jQuery,
jQuery.isEmptyObject()
será suficiente para ambos os casos,fonte
Se você estiver usando Angular:
Underscore.js:
fonte
1
à variávelx
? Preciso de sublinhado ou jQuery? (incrível que as pessoas vão usar bibliotecas mesmo para os mais operações elementares, como umtypeof
cheque)Eu uso
if (this.variable)
para testar se está definido. Simplesif (variable)
, recomendado acima , falha para mim. Acontece que ele funciona apenas quando variável é um campo de algum objeto,obj.someField
para verificar se está definido no dicionário. Mas podemos usarthis
ouwindow
como objeto de dicionário, já que qualquer variável é um campo na janela atual, pelo que entendi. Portanto, aqui está um testeEle primeiro detecta que a variável não
abc
está definida e é definida após a inicialização.fonte
Eu forneço três maneiras aqui para aqueles que esperam respostas estranhas:
isUndefined1:
Tente obter uma propriedade do valor de entrada, verifique a mensagem de erro, se existir. Se o valor de entrada for indefinido, a mensagem de erro será Uncaught TypeError: Não é possível ler a propriedade 'b' de undefined
isUndefined2:
Converta o valor de entrada em string para comparar
"undefined"
e garantir que seja um valor negativo.isUndefined3:
Em js, o parâmetro opcional funciona quando o valor de entrada é exatamente
undefined
.fonte
O ES2019 introduziu um novo recurso - encadeamento opcional que você pode usar para usar uma propriedade de um objeto apenas quando um objeto é definido assim:
Ele fará referência à propriedade phone somente quando user e contactDetails estiverem definidos.
Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
fonte
Retorna false se a variável estiver definida e true se não for definido.
Então use:
fonte
typeof
teste em uma função. Incrível que 4 pessoas votaram positivamente nisso. -1.Gostaria de mostrar uma coisa que estou usando para proteger a
undefined
variável:Isso proíbe qualquer pessoa de alterar o
window.undefined
valor, destruindo o código com base nessa variável. Se estiver usando"use strict"
, qualquer coisa que tente alterar seu valor terminará em erro, caso contrário, seria silenciosamente ignorado.fonte
você também pode usar o Proxy, ele funcionará com chamadas aninhadas, mas exigirá uma verificação extra:
então você o usará como:
fonte