Qual é a melhor maneira de verificar se uma propriedade de objeto em JavaScript é undefined
?
Qual é a melhor maneira de verificar se uma propriedade de objeto em JavaScript é undefined
?
Respostas:
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, como undefined = 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-javascript
Acredito 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.
A maneira mais robusta de executar este teste é:
if (typeof myVar === "undefined")
Isso sempre retornará o resultado correto e até lida com a situação em que myVar
não é declarado.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Além disso, myVar === undefined
haverá um erro na situação em que myVar não for declarado.
=== undefined
desconcertante. Sim, você pode atribuir a undefined
, 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 a True
e False
, 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 atribuir undefined
até vale a pena considerar aqui?
void 0
obter o valor que undefined
aponta para. Então você pode fazer if (myVar === void 0)
. o 0
não é especial, você pode literalmente colocar qualquer expressão lá.
undefined
. MDN: undefined
Apesar 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 valor undefined
, porque atua como uma verificação combinada do valor undefined
e da existência de uma variável. Na grande maioria dos casos, você sabe quando existe uma variável e typeof
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'
.
var snapshot = …;
if (typeof snaposhot === 'undefined') {
// ^
// misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;
if (typeof foo === 'undefned') {
// ^
// misspelled – this will never run, but it won’t throw an error!
}
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:
var foo = …;
if (foo === undefined) {
⋮
}
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 como bar()
) falhará. Isso simplesmente não é verdade - variáveis sem inicialização explícita e parâmetros que não receberam valores sempre se tornam undefined
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 a undefined
propriedade seja alterada e, a partir de 2017, esse é o caso há muito tempo. A falta de modo estrito também não afeta undefined
o comportamento - apenas faz declarações como undefined = 5
não fazer nada em vez de jogar. Como não é uma palavra-chave, você pode declarar variáveis com o nome undefined
, e essas variáveis podem ser alteradas, criando esse padrão outrora comum:
(function (undefined) {
// …
})()
mais perigoso do que usar o global undefined
. Se você precisar ser compatível com ES3, substitua undefined
por void 0
- não use typeof
. ( 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:
if (typeof foo.bar === 'undefined') {
⋮
}
é sempre exatamente equivalente a este³:
if (foo.bar === undefined) {
⋮
}
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 valor undefined
quando lido), presente no próprio objeto com o valor undefined
, presente no protótipo do objeto com o valor undefined
ou presente em qualquer um que não tenha undefined
valor. 'key' in obj
informará se uma chave está em algum lugar da cadeia de protótipos de um objeto e Object.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 de void 0
outra forma.
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):
Também existe um valor semelhante, null, cujo significado é 'esse valor é definido, mas não possui um valor'. A diferença de significado entre indefinido e nulo é principalmente acadêmica e geralmente não é muito interessante. Nos programas práticos, muitas vezes é necessário verificar se algo 'tem um valor'. Nesses casos, a expressão algo == indefinido pode ser usada, porque, embora não sejam exatamente o mesmo valor, nulo == indefinido produzirá verdadeiro.
Então, acho que a melhor maneira de verificar se algo estava indefinido seria:
if (something == undefined)
Espero que isto ajude!
Editar: em resposta à sua edição, as propriedades do objeto devem funcionar da mesma maneira.
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
undefined
é apenas uma variável que pode ser reatribuída pelo usuário: a gravação undefined = 'a';
fará com que seu código não faça mais o que você pensa. Usar typeof
é 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:
var o = { a: undefined }
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:
typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false
Podemos ver claramente isso typeof obj.prop == 'undefined'
e obj.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.
1) Você deseja saber se uma propriedade é indefinida pelo primeiro ou pelo segundo significado (a situação mais típica).
obj.prop === undefined // IMHO, see "final fight" below
2) Você quer apenas saber se o objeto tem alguma propriedade e não se importa com o seu valor.
'prop' in obj
x.a === undefined
ou isso typeof x.a == 'undefined'
aumenta ReferenceError: 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.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.O Node.js suporta a variável global undefined
como global.undefined
(também pode ser usada sem o prefixo 'global'). Não conheço outras implementações de JavaScript do lado do servidor.
undefined
como membro global
. Também nem console.log(global);
nem for (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 como typeof 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.
| typeof obj.x === 'undefined' | !("x" in obj)
1. { x:1 } | false | false
2. { x : (function(){})() } | true | false
3. {} | true | true
Vale ressaltar que esses testes também são iguais para as null
entradas
| typeof obj.x === 'undefined' | !("x" in obj)
{ x:null } | false | false
Eu 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.
if( typeof blob.x != 'undefined' ) { fn(blob.x); }
O que ficou mais claro quando escrito sem um cheque por indefinido.
if( "x" in blob ) { fn(blob.x); }
Mas, como já foi mencionado, estes não são exatamente os mesmos (mas são mais do que suficientes para minhas necessidades).
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ão typeof 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.) avalia undefined
(embora você mencionou isso mais tarde).
if ( typeof( something ) == "undefined")
Isso funcionou para mim, enquanto os outros não.
typeof (something == "undefined")
.
(typeof something) === "undefined"
.
Não tenho certeza de onde a origem de usar ===
com typeof
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?
typeof x; // some string literal "string", "object", "undefined"
if (typeof x === "string") { // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") { // sufficient
==
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
para in
testes faz diferença quando em um invólucro com escopo definido)
Código de referência:
(function(undefined) {
var definedButNotInitialized;
definedAndInitialized = 3;
someObject = {
firstProp: "1"
, secondProp: false
// , undefinedProp not defined
}
// var notDefined;
var tests = [
'definedButNotInitialized in window',
'definedAndInitialized in window',
'someObject.firstProp in window',
'someObject.secondProp in window',
'someObject.undefinedProp in window',
'notDefined in window',
'"definedButNotInitialized" in window',
'"definedAndInitialized" in window',
'"someObject.firstProp" in window',
'"someObject.secondProp" in window',
'"someObject.undefinedProp" in window',
'"notDefined" in window',
'typeof definedButNotInitialized == "undefined"',
'typeof definedButNotInitialized === typeof undefined',
'definedButNotInitialized === undefined',
'! definedButNotInitialized',
'!! definedButNotInitialized',
'typeof definedAndInitialized == "undefined"',
'typeof definedAndInitialized === typeof undefined',
'definedAndInitialized === undefined',
'! definedAndInitialized',
'!! definedAndInitialized',
'typeof someObject.firstProp == "undefined"',
'typeof someObject.firstProp === typeof undefined',
'someObject.firstProp === undefined',
'! someObject.firstProp',
'!! someObject.firstProp',
'typeof someObject.secondProp == "undefined"',
'typeof someObject.secondProp === typeof undefined',
'someObject.secondProp === undefined',
'! someObject.secondProp',
'!! someObject.secondProp',
'typeof someObject.undefinedProp == "undefined"',
'typeof someObject.undefinedProp === typeof undefined',
'someObject.undefinedProp === undefined',
'! someObject.undefinedProp',
'!! someObject.undefinedProp',
'typeof notDefined == "undefined"',
'typeof notDefined === typeof undefined',
'notDefined === undefined',
'! notDefined',
'!! notDefined'
];
var output = document.getElementById('results');
var result = '';
for(var t in tests) {
if( !tests.hasOwnProperty(t) ) continue; // bleh
try {
result = eval(tests[t]);
} catch(ex) {
result = 'Exception--' + ex;
}
console.log(tests[t], result);
output.innerHTML += "\n" + tests[t] + ": " + result;
}
})();
E resultados:
definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
Se você fizer
if (myvar == undefined )
{
alert('var does not exists or is not initialized');
}
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:
var myvar = 'test';
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:
if(window.myvar == undefined )
{
alert('var does not exists or is not initialized');
}
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 para myvar = undefined
or myvar = false
ou myvar = 0
.
Quando você espera um tipo específico, teste o tipo da variável. Para acelerar o teste de uma condição, é melhor:
if( !window.myvar || typeof window.myvar != 'string' )
{
alert('var does not exists or is not type of string');
}
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)
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):
if (obj && obj.prop) {
// Do something;
}
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).
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:
function isUndefined(obj){
return obj === void 0;
}
void 0
é apenas uma maneira curta de escrever undefined
(já que é o que o nulo seguido por qualquer expressão retorna), ele salva 3 caracteres. Também poderia funcionar var a; return obj === a;
, mas esse é mais um personagem. :-)
void
é uma palavra reservada, enquanto que undefined
não é ie, enquanto undefined
é igual void 0
por padrão, você pode atribuir um valor a undefined
eg undefined = 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:
function isUndefined(value) {return typeof value === 'undefined';}
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:
var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;
e verificamos como abaixo, você pode ver os resultados na frente deles como um comentário:
isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true
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.
isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)
Tão simples que você pode envolver dentro de uma declaração if como abaixo:
if(typeof x !== 'undefined') {
//do something
}
Qual também igual a isDefined no Angular 1.x ...
function isDefined(value) {return typeof value !== 'undefined';}
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).
Igualdade estrita e indefinida
É possível usar operadores de igualdade e desigualdade indefinidos e estritos para determinar se uma variável tem um valor. No código a seguir, a variável x não está definida e a instrução if é avaliada como verdadeira.
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
Nota: O operador de igualdade estrita, em vez do operador de igualdade padrão, deve ser usado aqui, porque x == undefined também verifica se x é nulo, enquanto a igualdade estrita não. null não é equivalente a indefinido. Consulte operadores de comparação para obter detalhes.
Operador Typeof e indefinido
Como alternativa, typeof pode ser usado:
var x;
if (typeof x === 'undefined') {
// these statements execute
}
Um motivo para usar typeof é que ele não gera um erro se a variável não tiver sido declarada.
// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
// these statements execute
}
if (x === undefined) { // throws a ReferenceError
}
No entanto, esse tipo de técnica deve ser evitado. JavaScript é uma linguagem com escopo estaticamente, portanto, saber se uma variável é declarada pode ser lido, verificando se ela é declarada em um contexto fechado. A única exceção é o escopo global, mas o escopo global está vinculado ao objeto global, portanto, a verificação da existência de uma variável no contexto global pode ser feita verificando a existência de uma propriedade no objeto global (usando o operador in, por exemplo).
Operador nulo e indefinido
O operador nulo é uma terceira alternativa.
var x;
if (x === void 0) {
// these statements execute
}
// y has not been declared before
if (y === void 0) {
// throws a ReferenceError (in contrast to `typeof`)
}
mais> aqui
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.
if (window.history) {
history.call_some_function();
}
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.
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.
Se o valor de um objeto nunca foi definido, isso impedirá o retorno true
se for definido como null
ou undefined
. Isso é útil se você deseja que true seja retornado para valores definidos comoundefined
if(obj.prop === void 0) console.log("The value has never been defined");
Se você deseja que resulte como true
para valores definidos com o valor de undefined
, ou nunca definidos, você pode simplesmente usar=== undefined
if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");
Geralmente, as pessoas me pedem um algoritmo para descobrir se um valor é falso undefined
, ou null
. Os seguintes trabalhos.
if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
console.log("The value is falsy, null, or undefined");
}
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
-> true
. Como isso é "nunca definido como undefined
"? Isto está errado.
Compare com void 0
, por concisão.
if (foo !== void 0)
Não é tão detalhado quanto if (typeof foo !== 'undefined')
foo
não for declarado.
A solução está incorreta. Em JavaScript,
null == undefined
retornará true, porque ambos são "convertidos" para um booleano e são falsos. A maneira correta seria verificar
if (something === undefined)
que é o operador de identidade ...
===
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.
function getAllUndefined(object) {
function convertPath(arr, key) {
var path = "";
for (var i = 1; i < arr.length; i++) {
path += arr[i] + "->";
}
path += key;
return path;
}
var stack = [];
var saveUndefined= [];
function getUndefiend(obj, key) {
var t = typeof obj;
switch (t) {
case "object":
if (t === null) {
return false;
}
break;
case "string":
case "number":
case "boolean":
case "null":
return false;
default:
return true;
}
stack.push(key);
for (k in obj) {
if (obj.hasOwnProperty(k)) {
v = getUndefiend(obj[k], k);
if (v) {
saveUndefined.push(convertPath(stack, k));
}
}
}
stack.pop();
}
getUndefiend({
"": object
}, "");
return saveUndefined;
}
jsFiddle link
getUndefiend
deveria getUndefined
.
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.
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
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.
typeof
guarda não se protege contra nada que uma comparação direta não possa suportar. Se restResult
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.
var a = obj.prop || defaultValue;
É adequado se você tiver uma função que receba uma propriedade de configuração adicional:
var yourFunction = function(config){
this.config = config || {};
this.yourConfigValue = config.yourConfigValue || 1;
console.log(this.yourConfigValue);
}
Agora executando
yourFunction({yourConfigValue:2});
//=> 2
yourFunction();
//=> 1
yourFunction({otherProperty:5});
//=> 1
Todas as respostas estão incompletas. Esta é a maneira correta de saber que existe uma propriedade 'definida como indefinida':
var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;
Exemplo:
var a = { b : 1, e : null } ;
a.c = a.d ;
hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null
// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined
Pena que esta foi a resposta certa, está enterrada em respostas erradas> _ <
Então, para quem passa, eu te darei indefinidos de graça !!
var undefined ; undefined ; // undefined
({}).a ; // undefined
[].a ; // undefined
''.a ; // undefined
(function(){}()) ; // undefined
void(0) ; // undefined
eval() ; // undefined
1..a ; // undefined
/a/.a ; // undefined
(true).a ; // undefined
Analisando os comentários, para quem deseja verificar os dois é indefinido ou seu valor é nulo:
//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
alert('either it is undefined or value is null')
}
Se você estiver usando a biblioteca jQuery, jQuery.isEmptyObject()
será suficiente para ambos os casos,
var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;
s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;
//Usage
if (jQuery.isEmptyObject(s)) {
alert('Either variable:s is undefined or its value is null');
} else {
alert('variable:s has value ' + s);
}
s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
Se você estiver usando Angular:
angular.isUndefined(obj)
angular.isUndefined(obj.prop)
Underscore.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
1
à variável x
? Preciso de sublinhado ou jQuery? (incrível que as pessoas vão usar bibliotecas mesmo para os mais operações elementares, como um typeof
cheque)
Eu uso if (this.variable)
para testar se está definido. Simples if (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 usar this
ou window
como objeto de dicionário, já que qualquer variável é um campo na janela atual, pelo que entendi. Portanto, aqui está um teste
if (this.abc) alert("defined"); else alert("undefined");
abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");
Ele primeiro detecta que a variável não abc
está definida e é definida após a inicialização.
Eu forneço três maneiras aqui para aqueles que esperam respostas estranhas:
function isUndefined1(val) {
try {
val.a;
} catch (e) {
return /undefined/.test(e.message);
}
return false;
}
function isUndefined2(val) {
return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
const defaultVal={};
return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
console.group(`test start :`+func.name);
console.log(func(undefined));
console.log(func(null));
console.log(func(1));
console.log(func("1"));
console.log(func(0));
console.log(func({}));
console.log(func(function () { }));
console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);
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
Converta o valor de entrada em string para comparar "undefined"
e garantir que seja um valor negativo.
Em js, o parâmetro opcional funciona quando o valor de entrada é exatamente undefined
.
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:
const userPhone = user?.contactDetails?.phone;
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
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Retorna false se a variável estiver definida e true se não for definido.
Então use:
if (isUnset(var)) {
// initialize variable here
}
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:
Object.defineProperty(window, 'undefined', {});
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.
você também pode usar o Proxy, ele funcionará com chamadas aninhadas, mas exigirá uma verificação extra:
function resolveUnknownProps(obj, resolveKey) {
const handler = {
get(target, key) {
if (
target[key] !== null &&
typeof target[key] === 'object'
) {
return resolveUnknownProps(target[key], resolveKey);
} else if (!target[key]) {
return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
}
return target[key];
},
};
return new Proxy(obj, handler);
}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }
então você o usará como:
const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
// do someting
}