How to check Undefined correctly in Javascript

Asked

Viewed 16,866 times

16

What is the best way to check whether an element/variable is undefined in Javascript? I’ve seen some examples using variavel === undefined and others using typeof variavel == "undefined".

  • Related (but in my opinion not a duplicate): http://answall.com/questions/19273/howto verify se-uma-vari%C3%A1vel-est%C3%A1-defined? Rq=1

3 answers

17


The most correct is to use typeof variavel === "undefined", for undefined may be superscripted using window.undefined, causing the comparison variavel === undefined return unexpected values.

In Ecmascript version 5, it is no longer possible to overwrite window.undefined, although by compatibility with older Engins it is recommended not to use this comparison format.

Note: some people use if ( variavel ) { to check if the variable is set. This is unreliable as variavel can have values that are interpreted as false, and therefore not entering the if even if the variable is defined.

If what you want is to check whether variavel has been declared, you must use the operator in. This happens because when a variable is declared, but is not initialized explicitly, implicitly it is initialized with the value undefined. Soon:

console.log(typeof x === "undefined"); // true
console.log("x" in window); // false
var x;
console.log(typeof x === "undefined"); // true
console.log(x in window); // true
  • 2

    Missing quotation marks on "x" in window. And by the way, this test only applies to top-level, right? Ex.: (function() { var x; console.log(x in window); })(); will yet return false.

  • Without reading the JS specification I don’t know how to argue, but, if you run: (function test() { var x; console.log("x" in window); })(); the result is false. But if you run (function test() { var x; console.log(x in window); })();, the restultated is true. I tested this using the Chrome developer console. Maybe the behavior is a little different when running inside a real page. About the quotes, in the first test (console.log(x in window); // false), they are really necessary. In the second, they interfere with the result.

  • 1

    That’s because he’s playing x like "the thing you want to know is there". If you do var x = "foo"; console.log(x in window); he will return false, but if you do var x = "Number"; console.log(x in window); he will return true. And if you do var x = "undefined"; console.log(x in window); he will return true (for window has a property called undefined). x in window is more or less like testing if window[x] exists. Therefore - although it is giving the correct value by "coincidence" - it is an incorrect form, because it is testing something else.

  • @mgibsonbr is right. And look at this example of yours: (function test() { var x; console.log(x in window); })();. This does not create a global variable (i.e., property of window; creates a path. What you are testing is whether there is a property called "Undefined" (which is the value of x) in window, so it gives true.

11

The two checks you mentioned serve for different things.

1. Variables not declared

If a variable has not been declared, with var variável = ..., you can’t use it in equality comparisons like if(variavel === undefined). That throws an error because the variable does not exist.

However, the operator typeof accepts an operand that does not exist. Therefore, one can use typeof variavel == "undefined" for that verification. And this test with typeof also serve to verify the second case:

2. Variables whose value is undefined

An existing variable may contain the value undefined. In that case, it is equivalent to check with variavel === undefined or typeof variavel == "undefined" - except in the case of the global variable undefined have been superscripted as Vinicius quoted in his reply, but this is no longer permitted by modern browsers.

8

Depends on what you want to test:

Whether or not a variable with that name exists

In that case, I would try to perform an operation on her and observe a ReferenceError:

var x;

try {
  x + 1;
  document.body.innerHTML += "<pre>x existe</pre>";
} catch(e) {
  if ( e instanceof ReferenceError )
    document.body.innerHTML += "<pre>x não existe</pre>";
  else
    throw e;
}

try {
  y + 1;
  document.body.innerHTML += "<pre>y existe</pre>";
} catch(e) {
  if ( e instanceof ReferenceError )
    document.body.innerHTML += "<pre>y não existe</pre>";
  else
    throw e;
}

Whether or not there is a variable global by that name

In this case (and only in this case) one can test for its presence in the global object (in browsers, window), as pointed out in answer from Vinicius:

var a;

document.body.innerHTML += "<pre>a " + ("a" in window ? "" : "não ") + "existe.</pre>";
document.body.innerHTML += "<pre>b " + ("b" in window ? "" : "não ") + "existe.</pre>";

// Não funciona com variáveis locais a uma função
(function() {
  var c;

  document.body.innerHTML += "<pre style='color:red'>c " + ("c" in window ? "" : "não ") + "existe.</pre>";
  document.body.innerHTML += "<pre>d " + ("d" in window ? "" : "não ") + "existe.</pre>";
})();

Whether a variable (existing or not) is undefined

Like pointed by bfavaretto, a variable may be existing, valid, until it has had value at some point, but at a certain point it may have received the value undefined. In many cases this situation is indistinguishable from the case where the variable simply doesn’t exist. But if you just want to know if it is other than undefined - i.e. if it is defined - you can use the typeof:

var a = 10;
var b;

document.body.innerHTML += "<pre>a" + (typeof(a) == "undefined" ? " não" : "") + " está definida.<pre>";
document.body.innerHTML += "<pre>b" + (typeof(b) == "undefined" ? " não" : "") + " está definida.<pre>";
document.body.innerHTML += "<pre>c" + (typeof(c) == "undefined" ? " não" : "") + " está definida.<pre>";

Okay, and in what situation can I directly compare with undefined?

Compare with undefined (or with void(0)) will cause a different response in each of the three cases above: will throw an exception if the variable does not exist, will return true if it exists but holds the value undefined, or return false if it exists but has another value. Note that the comparison should always be made with === or !==, never == or != (since the latter are too unpredictable to use safely).

"use strict";

var a = 10;
var b;

try {
  document.body.innerHTML += "<pre>a" + (a === undefined ? " não" : "") + " está definida.</pre>";
  document.body.innerHTML += "<pre>b" + (b === undefined ? " não" : "") + " está definida.</pre>";
  document.body.innerHTML += "<pre>c" + (c === undefined ? " não" : "") + " está definida.</pre>";
} catch(e) {
  document.body.innerHTML += "<pre>Erro: tentativa de acessar uma variável inexistente.</pre>";
}

Personally, I consider this form ok, because in general accessing a variable that has not been set is a programming error, not something you’ll want to test running (except for debugging purposes, of course). Simply use variavel === undefined and let the exception propagate, if variavel does not exist, seems to me an appropriate form of programming.

You can have a try..catch "Generic" just so the program doesn’t "explode" if an error like this goes unnoticed, but in my opinion it is useless to try to treat this exception. Because this situation is unexpected (if expected, you would simply correct it and declare the variable!), it is difficult for your program to do so recover from that error.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.