views:

484

answers:

7

Possible Duplicates:
Detecting an undefined object property in JavaScript
How to check for undefined in javascript?

What is the most appropriate way to test if a variable is undefined in js? I've seen people use

if (window.myVariable) 

also

if (typeof(myVariable) != "undefined")

and

if (myVariable) //this throws an error if undefined, should this be in Try/Catch?
A: 
if (my_var == undefined){
    // ...
}
opatut
Don't do this, use typeof instead
Abel
Don't do this, use `===` instead
trinithis
+17  A: 

If you are interested in finding out whether a variable has been declared regardless of its value, then using the in operator is the safest way to go. Consider this example.

// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"

But this may not be the intended result for some cases, since the variable or property was declared but just not initialized. Use the in operator for a more robust check.

"theFu" in window; // true
"theFoo" in window; // false

If you are interested in knowing whether the variable hasn't been declared or has the value undefined, then use the typeof operator.

if(typeof myVar != 'undefined')

The typeof operator is guaranteed to return a string. Direct comparisons against undefined are troublesome as undefined can be overwritten.

window.undefined = "omg";

"omg" == undefined // true

if(window.myVar) will also include all these falsy values, so it's not good:

false
0
""
NaN
null
undefined

Your third case - if (myVariable) should never throw an error.

Edit: The third case can only throw an error if it hasn't been declared at all, or you're using Object.defineProperty from ECMAScript 5th ed. where a property can have a backing function, and that backing function throws an error. For example.

// abc was never declared.
if(abc) {}

// or it's a property that can throw an error
Object.defineProperty(window, "myVariable", { 
    get: function() { throw new Error("W00t?"); }, 
    set: undefined 
});
if(myVariable) {}

The if line will throw an error now. Try it in Chrome.

Anurag
*This* ; +1. Any other solution is bound of fail at some point in time. :-)
sasuke
+1, great point about `window.undefined` ... learned something new!
Daniel Schaffer
@Anurag, the third case will throw a `ReferenceError` if `myVariable` is not *declared*...
CMS
@CMS - thanks, I somehow imagined `myVariable` was declared somewhere, just without a value.
Anurag
@Anurag, you're welcome, since you talk about ES5, maybe is worth mentioning that [`undefined`](http://ecma262-5.com/ELS5_HTML.htm#Section_15.1.1.3) is now described as non-writable, non-configurable and non-enumerable. So, `window.undefined = "omg";` will simply fail silently or throw under strict mode.
CMS
Comparing against a string ('undefined') sucks for minification though. What I like to do is create my own (guaranteed to be) `undefined` in an appropriate scope. Like in this pattern:`(function myScope(global, undefined) { /* do your checks against your own sacred undefined in this scope */ })(this);`I think for ex. jQuery (gasp!!!) has done this for a while.
npup
I abhor your argument against using `undefined`. (Also, you want triple equal signs for comparision against it.)
trinithis
Can "typeof" be redefined?
MakerOfThings7
typeof is a language statement, it cannot be redefined any more than if/else/while/for/function etc. could be.
MooGoo
@MooGoo If thats the case, then I'll infer that language statements in general can't be redefined ;)
MakerOfThings7
Would anyone know the minification difference between npup's approach and trinthis's approach of myVar === undefined
MakerOfThings7
If you're worried about minification, you can use a variable instead of a string literal to compare against an object's type: `var UNDEF = "undefined"; if (typeof someVar == UNDEF)...`
Tim Down
@MakerOfThings7 - My experience is that you can see improvements by declaring your own version of certain variables. Minifyers typically won't touch `this` either, so if it is referenced enough times, it is worth to do `var self = this;` in the scope and the minifyer will shorten it to `a` or something. Same thing with `undefined` - if you use it a couple of times in the scope, you can get the "wasted" chars (and more) back via the minifyer. And as for `undefined`, you are then also sure to get a **really** undefined `undefined`, which I think is great.
npup
A: 

I use it as a function parameter and exclude it on function execution that way I get the "real" undefined. Although it does require you to put your code inside a function. I found this while reading the jQuery source.

undefined = 2;

(function (undefined) {
   console.log(undefined); // prints out undefined
   // and for comparison:
   if (undeclaredvar === undefined) console.log("it works!")
})()

Of course you could just use typeof though. But all my code is usually inside a containing function anyways, so using this method probably saves me a few bytes here and there.

CD Sanchez
+1  A: 

Using typeof is the best way. It will work when the variable has never been declared, unlike any comparison with the == or === operators or type coercion using if. (undefined, unlike null, may also be redefined, making it unreliable for comparison).

if (typeof someUndeclaredVariable == "undefined") {
    // Works
}

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}
Tim Down
Why would you ever test undefinedness against a variable that is undeclared anyway? The only real use I have ever had for testing undefinedness has been against function arguments, which are declared. You can always look at your source code to discover undeclared variables in any case... without a runtime check [email protected]!!!
trinithis
You might want to check if a particular global variable representing a piece of functionality has already been defined. For example, library code may wish to check that the library has not already previously been included.
Tim Down
right.. forgot about those
trinithis
+1  A: 

I personally use

myVar === undefined

Warning: Please note that === is used over ==!

<rant> I do not buy the argument that undefined can be redefined. Sure it's true, but it's BS in my opinion to use that as an argument because just about ANYTHING in Javascript can be overwritten. Might as well not write any code at all because you "don't know what it does". How do I know Object, String, parseInt, etc. all are what they are? I don't, but there are assumptions one has to make. undefined is no different. </rant>

trinithis
It's marginally more likely that `undefined` could be redefined, just because people do use it for such checks. Some people habitually put the constant on the left-hand side when doing such checks: `if (undefined == someVariable)`. It only takes a typo for this to silently redefine `undefined`: `if (undefined = someVariable)`.
Tim Down
A: 

You need quotes if using typeof since it returns a string

johans