variable === undefined vs. typeof variable === “undefined”

variable === undefined vs. typeof variable === “undefined”

The jQuery Core Style Guidelines suggest two different ways to check whether a variable is defined.

Global Variables: typeof variable === “undefined”
Local Variables: variable === undefined
Properties: object.prop === undefined

Why does jQuery use one approach for global variables and another for locals and properties?

Solutions/Answers:

Solution 1:

For undeclared variables, typeof foo will return the string literal "undefined", whereas the identity check foo === undefined would trigger the error “foo is not defined”.

For local variables (which you know are declared somewhere), no such error would occur, hence the identity check.

Solution 2:

I’d stick to using typeof foo === "undefined" everywhere. That can never go wrong.

I imagine the reason why jQuery recommends the two different methods is that they define their own undefined variable within the function that jQuery code lives in, so within that function undefined is safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefined is faster and therefore decided it’s the way to go. [UPDATE: as noted in the comments, the comparison with undefined is also slightly shorter, which could be a consideration.] However, the gain in practical situations will be utterly insignificant: this check will never, ever be any kind of bottleneck, and what you lose is significant: evaluating a property of a host object for comparison can throw an error whereas a typeof check never will.

For example, the following is used in IE for parsing XML:

var x = new ActiveXObject("Microsoft.XMLDOM");

To check whether it has a loadXML method safely:

typeof x.loadXML === "undefined"; // Returns false

On the other hand:

x.loadXML === undefined; // Throws an error

UPDATE

Another advantage of the typeof check that I forgot to mention was that it also works with undeclared variables, which the foo === undefined check does not, and in fact throws a ReferenceError. Thanks to @LinusKleen for reminding me. For example:

typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError

Bottom line: always use the typeof check.

Solution 3:

Yet another reason for using the typeof-variant: undefined can be redefined.

undefined = "foo";
var variable = "foo";
if (variable === undefined)
  console.log("eh, what?!");

The result of typeof variable cannot.

Update: note that this is not the case in ES5.

Solution 4:

Who is interested in the performance gain of variable === undefined, may take a look here, but it seems to be a chrome optimization only.

Solution 5:

Because undefined is not always declared, but jQuery declares undefined in its main function. So they use the safe undefined value internally, but outside, they use the typeof style to be safe.

Solution 6:

For local variables, checking with localVar === undefined will work because they must have been defined somewhere within the local scope or they will not be considered local.

For variables which are not local and not defined anywhere, the check someVar === undefined will throw exception: Uncaught ReferenceError: j is not defined

Here is some code which will clarify what I am saying above. Please pay attention to inline comments for further clarity.

function f (x) {
    if (x === undefined) console.log('x is undefined [x === undefined].');
    else console.log('x is not undefined [x === undefined.]');

    if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
    else console.log('x is not undefined [typeof(x) === \'undefined\'].');

    // This will throw exception because what the hell is j? It is nowhere to be found.
    try
    {
        if (j === undefined) console.log('j is undefined [j === undefined].');
        else console.log('j is not undefined [j === undefined].');
    }
    catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}

    // However this will not throw exception
    if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
    else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};

If we call the above code like this:

f();

The output would be this:

x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

If we call the above code like these (with any value actually):

f(null); 
f(1);

The output will be:

x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.

When you do the check like this: typeof x === 'undefined', you are essentially asking this: Please check if the variable x exists (has been defined) somewhere in the source code. (more or less). If you know C# or Java, this type of check is never done because if it does not exist, it will not compile.

<== Fiddle Me ==>