Como verificar para "indefinido" em JavaScript? [duplicado]

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?
Author: Peter Mortensen, 2010-08-02

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
undefined
Obrigado 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?
}
 2200
Author: Anurag, 2014-07-01 11:28:30

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.)

Agora algumas pessoas vão morrer de dor quando lerem isto, gritando: "espera! WAAITTT!!! Pode ser redefinido!" Fixe. Eu sei disso. Mais uma vez, a maioria das variáveis em Javascript pode ser redefinido. Nunca deve usar um identificador incorporado que possa ser redefinido? Se seguires esta regra, ainda bem para ti: não és hipócrita.

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.)
 918
Author: Thomas Eding, 2015-03-28 08:02:01

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
}
 155
Author: Tim Down, 2015-05-05 08:37:38

Tem de utilizar typeof .

if (typeof something != "undefined") {
    // ...
}
 53
Author: Jacob Relkin, 2014-10-04 23:09:04

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);
}
 20
Author: Guffa, 2010-06-06 20:33:01
Alguns cenários que ilustram os resultados das várias respostas: http://jsfiddle.net/drzaus/UVjM4/

(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
 17
Author: drzaus, 2013-01-13 17:18:23
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.

 16
Author: Mathias Bynens, 2010-06-06 20:26:37

Em Este artigo li que quadros como sublinham.JS use esta função:

function isUndefined(obj){
    return obj === void 0;
}
 15
Author: Marthijn, 2014-11-23 13:39:38

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
}
 10
Author: Joseph Gabriel, 2014-02-19 13:20:54

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.
 9
Author: Hrishi, 2015-03-05 13:58:10

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'
Mesmo quando modifiquei os testes para evitar que o cromado os optimizasse, as diferenças eram insignificantes. Como tal, recomendo 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.

 9
Author: Zenexer, 2018-07-26 03:36:54
Como nenhuma das outras respostas me ajudou, sugiro fazer isto. Funcionou comigo no Internet Explorer 8:
if (typeof variable_name.value === 'undefined') {
    // variable_name is undefined
}
 4
Author: anmarti, 2014-11-23 13:31:46
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
   // These statements execute.
}

if (x === undefined) { // Throws a ReferenceError

}
 3
Author: sourcecode, 2014-11-23 13:38:10

Ao contrário da resposta de @ Thomas Eding:

Se me esquecer de declarar myVar 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.");
 3
Author: Vikas, 2014-11-23 13:41:10
    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 
 1
Author: Gaurav, 2014-11-23 13:37:02

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.

 0
Author: Cristian Sanchez, 2010-08-02 18:02:21