Detecção de propriedade de objeto indefinida

Qual é a melhor maneira de verificar se uma propriedade de um objeto em JavaScript é indefinida?

2533
26 авг. definido por Matt Sheppard 26 ago. 2008-08-26 10:25 '08 às 10:25 2008-08-26 10:25
@ 43 respostas
  • 1
  • 2

Use:

 if (typeof something === "undefined") { alert("something is undefined"); } 

Se uma variável de objeto tem algumas propriedades, você pode usar a mesma coisa como isto:

 if (typeof my_obj.someproperties === "undefined"){ console.log('the property is not available...'); // print into console } 
2431
06 янв. a resposta é dada Erwin 06 jan. 2009-01-06 15:27 '09 às 15:27 2009-01-06 15:27

Eu acredito que há um número de respostas incorretas neste tópico. Ao contrário da crença popular, "indefinido" não é uma palavra - chave em JavaScript e pode, na verdade, ter um valor atribuído a ela.

Código correto

O caminho certo para realizar este teste:

 if (typeof myVar === "undefined") 
border=0

Isso sempre retorna o resultado correto e até lida com uma situação em que myVar não myVar declarado.

Código degenerado. NÃO USE.

 var undefined = false; // Shockingly, this is completely legal! if (myVar === undefined) { alert("You have been misled. Run away!"); } 

Além disso, myVar === undefined causará um erro em uma situação em que myVar não seja declarado.

837
23 авг. Responder MarkPflug 23 ago. 2010-08-23 21:03 '10 às 21:03 2010-08-23 21:03

Embora eu recomende muitas outras respostas aqui, o typeof é uma má escolha. Nunca deve ser usado para verificar se as variáveis ​​têm o valor undefined , pois ele atua como um teste combinado do valor undefined e para determinar se a variável existe. Na esmagadora maioria dos casos, você sabe quando existe uma variável, e typeof simplesmente representa o potencial para uma falha silenciosa se você criar 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! } 

Então, se você não detectar a função de detecção2, onde há incerteza se o nome dado será um escopo (por exemplo, typeof module !== 'undefined' teste de typeof module !== 'undefined' como uma etapa no código específico do CommonJS), typeof é uma escolha prejudicial quando usando uma variável, e a opção correta é uma comparação direta do valor:

 var foo = …; if (foo === undefined) { ⋮ } 

Alguns equívocos comuns sobre isso incluem:

  • que ler a variável "uninitialized" ( var foo ) ou um parâmetro ( function bar(foo) { … } , chamada bar() ) falhará com um erro. Isso simplesmente não é verdade: variáveis ​​sem inicialização explícita e parâmetros que não especificam um valor sempre se tornam undefined e estão sempre no escopo.

  • que undefined pode ser substituído. Há muito mais que isso. undefined não undefined uma palavra chave em javascript. Em vez disso, sua propriedade em um objeto global com um valor de indefinido. No entanto, desde ES5, essa propriedade era somente leitura e não configurável. Nenhum navegador moderno permitirá que você altere a propriedade undefined e, desde 2017, isso vem ocorrendo há muito tempo. A falta de modo estrito não afeta o comportamento de undefined s - simplesmente faz declarações como undefined = 5 não fazendo nada, não jogando. Como isso não é uma palavra-chave, você pode declarar variáveis ​​chamadas undefined e essas variáveis ​​podem ser alteradas, o que torna esse modelo único:

     (function (undefined) { // … })() 

    mais perigoso do que usar global undefined . Se você precisar ser compatível com ES3, substitua undefined por void 0 - não entre em contato com typeof . (Um void sempre foi um operador unário que avalia o valor indefinido de qualquer operando.)

Com o modo como as variáveis ​​trabalham de lado, é hora de decidir a questão real: as propriedades do objeto. Não faz sentido usar typeof para propriedades do objeto. A exceção anterior em relação à detecção de uma função não se aplica aqui - typeof tem apenas um comportamento especial para variáveis, e expressões que se referem às propriedades de um objeto não são variáveis.

Isto é:

 if (typeof foo.bar === 'undefined') { ⋮ } 

sempre exatamente equivalente a isso:

 if (foo.bar === undefined) { ⋮ } 

e tendo em conta o conselho acima, não confundir os leitores sobre o motivo pelo qual você usa typeof , porque faz sentido usar === para verificar a igualdade, porque ele pode ser reorganizado para verificar o valor das variáveis ​​mais tarde, e porque parece melhor, você deve sempre usar === undefined ³ aqui .

Outra coisa a considerar quando se trata de propriedades de objeto é se você realmente quer ou não verificar undefined . O nome desta propriedade pode estar ausente no objeto (ao ler o valor de undefined ) presente no próprio objeto com o valor undefined , presente no protótipo de objetos com valor undefined ou presente em qualquer daqueles cujo valor não é undefined . 'key' in obj lhe dirá se a chave está na cadeia de protótipos de objetos, e Object.prototype.hasOwnProperty.call(obj, 'key') dirá se está diretamente no objeto. Não vou entrar em detalhes nesta resposta protótipo e usar os objetos na forma de mapas com ligações de teclas, no entanto, porque é principalmente destinado a lidar com todos os maus conselhos em outras respostas, independentemente das possíveis interpretações da questão original. Leia os objetos protótipos no MDN para mais!

¹ escolha incomum de nome da variável, por exemplo? Este é um código morto real da extensão NoScript para o Firefox
² não assuma que, sem saber qual é o significado, em geral, tudo está em ordem. vulnerabilidade de bônus causada por abuso de uma área dinâmica: Projeto Zero 1225
³ aceita novamente o ambiente ES5 + e o undefined refere-se à propriedade undefined do objeto global. substitua void 0 caso contrário.

161
27 февр. A resposta é dada Ry- 27 de fevereiro 2014-02-27 00:17 '14 às 0:17 2014-02-27 00:17

JavaScript tem nulo e não está definido . Eles têm significados diferentes.

  • undefined significa que o valor da variável é indefinido; não se sabe qual é esse significado.
  • null significa que o valor da variável é definido e definido como null (sem valor).

Mariein Haverbecke em seu ebook JavaScript eloquente livre (minha atenção):

Existe também um valor similar, null, cujo valor "este valor é definido, mas não tem valor". A diferença de significado entre indefinido e zero é principalmente acadêmica, e geralmente isso não é muito interessante. Em programas práticos, muitas vezes é necessário verificar se algo é importante. "Nesses casos, a expressão algo == undefined pode ser usada porque, embora eles não sejam exatamente o mesmo valor, null == undefined retornará true.

Então, acho que a melhor maneira de verificar se algo está indefinido:

 if (something == undefined) 

Espero que isso ajude!

Edit: Em resposta à sua edição, as propriedades do objeto devem funcionar da mesma forma.

 var person = { name: "John", age: 28, sex: "male" }; alert(person.name); // "John" alert(person.fakeVariable); // undefined 
142
26 авг. A resposta é dada Pandincus 26 ago. 2008-08-26 10:36 '08 às 10:36 am 2008-08-26 10:36

O que isso significa: "propriedade indefinida de um objeto ?

Na verdade, isso poderia significar duas coisas completamente diferentes! Primeiro, pode significar uma propriedade que nunca foi definida em um objeto e, segundo, pode significar uma propriedade com um valor indefinido. Veja este código:

 var o = { a: undefined } 

É oa indefinido? Sim Seu valor é indefinido. É ob indefinido? Claro! Não existe nenhuma propriedade 'b'! Bem, veja como diferentes abordagens se comportam em ambas as situações:

 typeof oa == 'undefined' // true typeof ob == 'undefined' // true oa === undefined // true ob === undefined // true 'a' in o // true 'b' in o // false 

Podemos ver claramente que typeof obj.prop == 'undefined' e obj.prop === undefined equivalentes, e eles não distinguem entre essas diferentes situações. E 'prop' in obj pode detectar uma situação em que a propriedade não foi definida e não presta atenção ao valor da propriedade, que pode ser indefinida.

Então o que fazer?

1) Você quer saber se a propriedade indefinida é o primeiro ou o segundo valor (a situação mais típica).

 obj.prop === undefined // IMHO, see "final fight" below 

2) Você só quer saber se um objeto tem uma propriedade e não se importa com seu valor.

 'prop' in obj 

Notas:

  • Você não pode verificar simultaneamente um objeto e sua propriedade. Por exemplo, este xa === undefined ou este typeof xa == 'undefined' chamadas ReferenceError: x is not defined se x não está definido.
  • A variável undefined é uma variável global (portanto, é window.undefined nos navegadores). É suportado com ECMAScript 1st Edition, e com ECMAScript 5 é somente leitura . Portanto, em navegadores modernos, não pode ser redefinido para a verdade, como muitos autores gostam de nos assustar, mas isso ainda é verdade para navegadores mais antigos.

Luta final: obj.prop === undefined vs typeof obj.prop == 'undefined'

Vantagens obj.prop === undefined :

  • É um pouco mais curto e parece um pouco mais bonito.
  • O mecanismo de javascript lhe dará uma mensagem de erro se você tiver um erro com undefined

Desvantagens obj.prop === undefined :

  • undefined pode ser substituído em navegadores mais antigos.

Prós do typeof obj.prop == 'undefined' :

  • É verdadeiramente universal! Funciona em navegadores novos e antigos.

Desvantagens do typeof obj.prop == 'undefined' :

  • 'undefned' (com um erro) é apenas uma constante de string, então o mecanismo JavaScript não pode ajudá-lo se você tiver um erro, como se eu tivesse acabado de fazê-lo.

Atualização (para javascript do lado do servidor):

O Node.js suporta a variável global undefined como global.undefined (também pode ser usado sem o prefixo 'global'). Eu não sei sobre outras implementações de JavaScript do lado do servidor.

109
08 авг. resposta dada por Konstantin Smolyanin 08 ago. 2013-08-08 23:28 '13 às 23:28 2013-08-08 23:28

O problema resume-se a três casos:

  • O objeto tem uma propriedade e seu valor não é undefined .
  • O objeto tem uma propriedade e seu valor é undefined .
  • O objeto não tem propriedade.

Isso nos diz algo importante:

Há uma diferença entre um membro indefinido e um membro específico com 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 

Deve-se notar que esses testes são os mesmos para entradas null também.

  | typeof obj.x === 'undefined' | !("x" in obj) { x:null } | false | false 

Eu diria que em alguns casos faz sentido (e mais claramente) checar se esta propriedade está lá do que checar se ela está indefinida, e o único caso onde esta checagem será diferente é o caso 2, um caso raro da entrada real em Um objeto com um valor de indefinido.

Por exemplo: Acabei de reelaborar um monte de código que tinha um monte de verificações para ver se um objeto tinha uma propriedade especificada.

 if( typeof blob.x != 'undefined' ) { fn(blob.x); } 

Qual foi mais claro ao escrever sem verificação de indefinido.

 if( "x" in blob ) { fn(blob.x); } 

Mas, como já mencionado, isso não é exatamente o mesmo (mas mais do que suficiente para minhas necessidades).

62
08 июня '11 в 7:04 2011-06-08 07:04 Resposta é dada por Michael Anderson em 08 de junho '11 às 7:04 am 2011-06-08 07:04
 if ( typeof( something ) == "undefined") 

Funcionou para mim, outros não.

40
27 июля '10 в 19:03 2010-07-27 19:03 respondeu a Kevin em 27 de julho às 19:03 2010-07-27 19:03

Eu não sei de onde o uso de === com typeof veio, e como uma convenção eu vejo, ele é usado em muitas bibliotecas, mas o operador typeof retorna um literal de string, e nós sabemos o que está na frente dele, então por que você também quer digitar e confira?

 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 
35
22 сент. A resposta é dada por Eric em 22 de setembro. 2010-09-22 17:20 '10 às 17:20 2010-09-22 17:20

Resposta cruzada para minha resposta em uma questão relacionada Como verificar se há "indefinido" em JavaScript?

Específico para esta questão, veja someObject.<whatever> exemplos de someObject.<whatever> com someObject.<whatever> .


Alguns cenários ilustrando os resultados de várias respostas: http://jsfiddle.net/drzaus/UVjM4/

(Observe que usar var in testes é importante ao usar um shell com um determinado escopo)

Código para 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 os 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 
21
13 янв. A resposta é dada drzaus 13 de janeiro 2013-01-13 20:43 '13 às 8:43 pm 2013-01-13 20:43

Se você fizer

 if (myvar == undefined ) { alert('var does not exists or is not initialized'); } 

ele não funcionará se a variável myvar não existir, porque myvar não está definido, então o script está quebrado e o teste não tem efeito.

Como o objeto window possui um escopo global (o objeto padrão) fora da função, a declaração será anexada ao objeto window.

Por exemplo:

 var myvar = 'test'; 

A variável global myvar é a mesma que window.myvar ou window ['myvar']

Para evitar erros para verificar quando existe uma variável global, é melhor usar:

 if(window.myvar == undefined ) { alert('var does not exists or is not initialized'); } 

A questão de se uma variável realmente existe não importa, seu valor está incorreto. Caso contrário, é tolice inicializar variáveis ​​com undefined, e é melhor usar false para inicialização. Quando você sabe que todas as variáveis ​​que você declara são inicializadas com false, você pode simplesmente verificar seu tipo ou confiar em !window.myvar para verificar se possui o valor correto / válido. Assim, mesmo que a variável não esteja definida, então !window.myvar o mesmo para myvar = undefined ou myvar = false ou myvar = 0 .

Quando você espera um tipo específico, verifique o tipo da variável. Para acelerar o teste de estado, é melhor você:

 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 é verdadeira, o interpretador ignora os seguintes testes.

É sempre melhor usar uma variável instance / object para verificar se ela possui um valor válido. É mais estável e é a melhor maneira de programar.

(y)

16
12 авг. A resposta é dada por Codebeat 12 ago. 2011-08-12 17:40 '11 às 17:40 2011-08-12 17:40

Eu não vi (espero não ter perdido), alguém verificou o objeto na frente da propriedade. Então, isso é o mais curto e mais eficaz (embora não necessariamente o mais claro):

 if (obj  obj.prop) { // Do something; } 

Se obj ou obj.prop estiver indefinido, nulo ou "falso", a instrução if não executará um bloco de código. Este é geralmente o comportamento desejado na maioria dos operadores de bloco de código (em javascript).

15
25 сент. resposta dada por Joe Johnson em 25 de setembro. 2012-09-25 21:41 '12 em 9:41 pm 2012-09-25 21:41

No artigo Explorando Abismo de Nulo e Indefinido em JavaScript, eu li que frameworks como Underscore.js usam essa função:

 function isUndefined(obj){ return obj === void 0; } 
12
19 дек. A resposta é dada por Marthijn em 19 de dezembro. 2013-12-19 13:44 '13 às 13:44 2013-12-19 13:44

'if (window.x) {}' está seguro com um erro

Muito provavelmente, você quer if (window.x) . Esta verificação é segura mesmo que x não tenha sido declarado ( var x; ) - o navegador não apresenta um erro.

Exemplo: quero saber se meu navegador suporta APIs de histórico.

 if (window.history) { history.call_some_function(); } 

Como funciona:

Uma janela é um objeto que contém todas as variáveis ​​globais como seus membros, e é legal tentar obter acesso a um elemento inexistente. Se x não foi declarado ou não foi definido, window.x retorna indefinido . indefinido causa falso quando if () o avalia.

10
10 февр. Responder DenisS 10 de fev 2014-02-10 19:26 '14 às 19:26 2014-02-10 19:26
 "propertyName" in obj //-> true | false 
9
05 мая '14 в 3:13 2014-05-05 03:13 a resposta é dada 05 de maio de 2014 às 3:13 2014-05-05 03:13

Depois de ler isto, fico espantado por não ter visto isso. Eu encontrei vários algoritmos que irão trabalhar para isso.

Nunca definido

Se o valor do objeto nunca foi definido, ele impedirá o retorno de true se for definido como null ou undefined . Isso é útil se você quiser retornar true para valores definidos como undefined

 if(obj.prop === void 0) console.log("The value has never been defined"); 

Definido como indefinido ou nunca definido

Se você quiser que o resultado seja true para valores definidos com o valor undefined ou nunca determinado, você pode simplesmente usar === undefined

 if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined"); 

Definido como falsidade, indefinido, nulo ou nunca definido.

Como regra, as pessoas me pediram para desenvolver um algoritmo se o valor for falso, undefined ou null . O trabalho a seguir.

 if(obj.prop == false || obj.prop === null || obj.prop === undefined) { console.log("The value is falsy, null, or undefined"); } 
9
15 февр. A resposta é dada por Travis em 15 de fevereiro. 2015-02-15 06:10 '15 às 6:10 2015-02-15 06:10

Você pode obter uma matriz de todos os indefinidos usando 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

8
17 окт. Resposta dada por Anoop em 17 Out 2011-10-17 14:22 '11 às 2:22 pm 2011-10-17 14:22

A decisão está incorreta. Em javascript

 null == undefined 

retorna true, porque ambos são "lançados" para um valor booleano e são falsos. A maneira correta é verificar

 if (something === undefined) 

qual é o operador de identidade ...

7
26 авг. Resposta dada por Ricky 26 ago. 2008-08-26 15:38 '08 às 15:38 2008-08-26 15:38

Compare com void 0 para paciência.

 if (foo !== void 0) 

Isto não é tanto quanto if (typeof foo !== 'undefined')

7
02 янв. a resposta é dada bevacqua 02 jan. 2014-01-02 15:59 '14 às 15:59 2014-01-02 15:59

Apenas algo não é definido em JavaScript, não definido , não importa se é uma propriedade dentro de Object / Array ou apenas como uma variável ...

Em JavaScript, há um typeof que typeof muito fácil detectar uma variável indefinida.

Просто проверьте, является ли typeof whatever === 'undefined' и он вернет логическое значение.

Вот как isUndefined() знаменитая функция isUndefined() в AngularJs v.1x:

 function isUndefined(value) {return typeof value === 'undefined';} 

Итак, как вы видите, функция получает значение, если это значение определено, она вернет false , в противном случае для неопределенных значений вернет true .