Como verificar para "indefinido" em JavaScript? [duplicado]
- a detectar uma propriedade objecto indefinida 42 respostas
- Como verificar uma variável não definida em JavaScript 13 Respostas
- Como lidar com 'indefinido' em javascript [duplicate] 3 respostas
- Como verificar se existe uma variável em javascript? 8 respostas
Qual é a forma mais apropriada de testar se uma variável é indefinida em JavaScript? Já vi várias possíveis formas:
if (window.myVariable)
ou
if (typeof(myVariable) != "undefined")
ou
if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?
16 answers
Se estiver interessado em saber se uma variável foi declarada independentemente do seu valor, então usar o operador in
é o caminho mais seguro. Considere este exemplo.
// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"
Mas este pode não ser o resultado pretendido para alguns casos, uma vez que a variável ou propriedade foi declarada, mas apenas não inicializada. Use o operador in
para uma verificação mais robusta.
"theFu" in window; // true
"theFoo" in window; // false
Se estiver interessado em saber se a variável não foi declarada ou se tem o valor undefined
, então use o operador typeof
.
if (typeof myVar != 'undefined')
O operador typeof
tem a garantia de devolver um texto. Comparações diretas contra undefined
são problemáticas porque undefined
pode ser substituído.
window.undefined = "omg";
"omg" == undefined // true
Como @CMS salientou, isto foi corrigido no ECMAScript 5th ed., e undefined
não pode ser escrito.
if (window.myVar)
irá também incluir estes valores de falsidade, por isso não é muito robusto:
false 0 "" NaN null undefinedObrigado a @CMS por ter apontado que o seu terceiro caso -
if (myVariable)
também pode lançar um erro em dois vez. A primeira é quando a variável não foi definida, o que lança um ReferenceError
.
// abc was never declared.
if (abc) {
// ReferenceError: abc is not defined
}
O outro caso é quando a variável foi definida, mas tem uma função getter que lança um erro quando invocado. Por exemplo,
// or it's a property that can throw an error
Object.defineProperty(window, "myVariable", {
get: function() { throw new Error("W00t?"); },
set: undefined
});
if (myVariable) {
// Error: W00t?
}
Eu uso pessoalmente
myVar === undefined
Atenção: Por favor, note que ===
é usado em ==
e que myVar
foi anteriormente declarado (não definido).
Eu não gosto typeof myVar === "undefined"
. Penso que é longo e desnecessário. (Eu posso fazer o mesmo em menos código.)
A coisa é, para fazer muito trabalho real em JS, os desenvolvedores precisam confiar em identificadores redefiníveis para serem o que são. Não ouço pessoas a dizerem-me que não devia usar porque alguém pode ...
window.setTimeout = function () {
alert("Got you now!");
};
Resumindo, o argumento" pode ser redefinido " para não usar um raw === undefined
é falso.
(se ainda tem medo de undefined
ser redefinido, porque é que está a integrar cegamente o código de biblioteca não testado na sua base de códigos? Ou ainda mais simples: uma ferramenta de corte.)
Também, como a abordagem typeof
, esta técnica pode "detectar" variáveis não declaradas:
if (window.someVar === undefined) {
doSomething();
}
Mas ambas as técnicas vazam na sua abstração. Peço-te que não uses isto nem sequer
if (typeof myVar !== "undefined") {
doSomething();
}
Considere:
var iAmUndefined;
Para capturar, quer essa variável seja ou não declarada, você pode ser necessário recorrer ao operador in
. (Em muitos casos, você pode simplesmente ler o código O_o).
if ("myVar" in window) {
doSomething();
}
Mas espera! Há mais! E se estiver a acontecer um protótipo de magia em cadeia? Agora mesmo o operador superior in
não é suficiente. Está bem, já acabei esta parte excepto dizer que por 99% das vezes, === undefined
(e **** * tosse**** typeof
) funciona muito bem. Se você realmente se importa, você pode ler sobre este assunto por conta própria.)
Usar typeof
é a minha preferência. Funcionará quando a variável nunca tiver sido declarada, ao contrário de qualquer comparação com os operadores ==
ou ===
ou coação de tipo usando if
. (undefined
, ao contrário de null
, também pode ser redefinido em ambientes ECMAScript 3, tornando-o pouco fiável para comparação, embora quase todos os ambientes comuns estejam agora em conformidade com o ECMAScript 5 ou acima).
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
Tem de utilizar typeof
.
if (typeof something != "undefined") {
// ...
}
Se não for definido, não será igual a uma cadeia que contém os caracteres "indefinido", uma vez que a cadeia não é indefinida.
Pode verificar o tipo da variável:
if (typeof(something) != "undefined") ...
Às vezes nem tens de verificar o tipo. Se o valor da variável não pode ser avaliado como falso quando está definido (por exemplo, se é uma função), então você pode apenas avaliar a variável. Exemplo:
if (something) {
something(param);
}
(Note-se que a utilização de var
para os ensaios in
faz a diferença quando num invólucro delimitado)
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
if (typeof foo == 'undefined') {
// Do something
};
Note que a comparação estrita (!==
) não é necessária neste caso, uma vez que typeof
irá sempre devolver uma cadeia de caracteres.
Em Este artigo li que quadros como sublinham.JS use esta função:
function isUndefined(obj){
return obj === void 0;
}
A forma mais fiável que conheço de verificar undefined
é usar void 0
.
Isto é compatível com navegadores mais novos e mais antigos, da mesma forma, e não pode ser substituído como window.undefined
pode em alguns casos.
if( myVar === void 0){
//yup it's undefined
}
Pessoalmente, uso sempre o seguinte:
var x;
if( x === undefined) {
//Do something here
}
else {
//Do something else here
}
A janela.a propriedade indefinida não pode ser escrita em todos os navegadores modernos (JavaScript 1.8.5 ou posterior). A partir da Mozilla documentação: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, eu vejo isto: Uma razão para usar typeof() é que ele não lança um erro se a variável não foi definido.
Prefiro ter a abordagem de usar
x === undefined
Porque falha. e explode na minha cara em vez de passar em silêncio/falhar se x não foi declarado antes. Isto Alerta-me que o x não foi declarado. Acredito que todas as variáveis usadas no JavaScript devem ser declaradas.
Actualização 2018-07-25
Já passaram quase cinco anos desde que este post foi feito, e o JavaScript percorreu um longo caminho. Ao repetir os testes no post original, não encontrei uma diferença consistente entre os seguintes métodos de ensaio:abc === undefined
abc === void 0
typeof abc == 'undefined'
typeof abc === 'undefined'
abc === undefined
para clareza.
Teor relevante de:chrome://version
:
- Google Chrome: 67.0.3396.99 (Compilação Oficial) (64-bits) (coorte: Estável)
- revisão: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@{#790}
- OS: Windows
- JavaScript: V8 6. 7. 288. 46
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Data da publicação Original 2013-11-01
No Google Chrome, o seguinte foi sempre ligeiramente mais rápido do que um teste typeof
:
if (abc === void 0) {
// Undefined
}
A diferença foi insignificante. No entanto, este código é mais conciso, e mais claro de relance para alguém que sabe o que significa void 0
. Note, no entanto, que abc
ainda deve ser declarado.
Ambos typeof
e void
foram significativamente mais rápidos do que comparar directamente com undefined
. Usei o seguinte formato de teste na consola de desenvolvimento do Chrome:
var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
if (TEST) {
void 1;
}
}
end = +new Date();
end - start;
A os resultados foram os seguintes:
Test: | abc === undefined abc === void 0 typeof abc == 'undefined'
------+---------------------------------------------------------------------
x10M | 13678 ms 9854 ms 9888 ms
x1 | 1367.8 ns 985.4 ns 988.8 ns
Note que a primeira linha é em millisegundos, enquanto a segunda linha é em Nanosegundos. Uma diferença de 3,4 nanossegundos não é nada. Os tempos foram bastante consistentes nos testes subsequentes.
if (typeof variable_name.value === 'undefined') {
// variable_name is undefined
}
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
Ao contrário da resposta de @ Thomas Eding:
Se me esquecer de declararmyVar
no meu código, então vou conseguir myVar is not defined
.
Vejamos um exemplo real:
Tenho um nome variável, mas não sei se é declarado algures ou não.
Então a resposta de @Anurag vai ajudar:
var myVariableToCheck = 'myVar';
if (window[myVariableToCheck] === undefined)
console.log("Not declared or declared, but undefined.");
// Or you can check it directly
if (window['myVar'] === undefined)
console.log("Not declared or declared, but undefined.");
var x;
if (x === undefined) {
alert ("I am declared, but not defined.")
};
if (typeof y === "undefined") {
alert ("I am not even declared.")
};
/* One more thing to understand: typeof ==='undefined' also checks
for if a variable is declared, but no value is assigned. In other
words, the variable is declared, but not defined. */
// Will repeat above logic of x for typeof === 'undefined'
if (x === undefined) {
alert ("I am declared, but not defined.")
};
/* So typeof === 'undefined' works for both, but x === undefined
only works for a variable which is at least declared. */
/* Say if I try using typeof === undefined (not in quotes) for
a variable which is not even declared, we will get run a
time error. */
if (z === undefined) {
alert ("I am neither declared nor defined.")
};
// I got this error for z ReferenceError: z is not defined
Eu uso-o como um parâmetro de função e excluo-o na execução da função dessa forma eu fico o "real" indefinido. Embora exija que coloque o seu código dentro de uma função. Encontrei isto ao ler a fonte do jQuery.
undefined = 2;
(function (undefined) {
console.log(undefined); // prints out undefined
// and for comparison:
if (undeclaredvar === undefined) console.log("it works!")
})()
Claro que podes usar typeof
. Mas todo o meu código está geralmente dentro de uma função contendo de qualquer maneira, então usando este método provavelmente me salva alguns bytes aqui e ali.