1

I've never understood the difference in these two ways for testing the existence of an object...

typeof obj == "undefined"

vs.

obj == undefined

Is one preferred? I'm almost always using jQuery, is the second a jQuery only feature?

CambridgeMike
  • 4,562
  • 1
  • 28
  • 37
  • 3
    possible duplicate of [Should I use typeof in Javascript type equality?](http://stackoverflow.com/questions/6481802/should-i-use-typeof-in-javascript-type-equality) and maybe [variable === undefined vs. typeof variable === “undefined”](http://stackoverflow.com/questions/4725603/variable-undefined-vs-typeof-variable-undefined) – Felix Kling Nov 04 '11 at 16:39
  • 4
    "is it a jQuery feature". Seriously? – Raynos Nov 04 '11 at 16:40

2 Answers2

4

The problem with

obj === undefined 

is that if the 'obj' identifier name doesn't exist in the (lexical) environment (or any of the outer environments), an error is thrown (which in turn breaks your program).

Btw names are bound to the environment by either declaring a variable (var x;), or assigning properties to the window object (window.x = ...;).

On the other hand

typeof obj === 'undefined'

doesn't throw (an error), and is therefore the preferred method.


Note though that you can't check for object existence in JavaScript. JavaScript code doesn't deal with objects directly, but trough references. If a given reference doesn't point to an object that doesn't mean that the object doesn't exist (it may be referenced by a different reference). What you can do is check whether or not a reference (like obj in your case) points to an Object value (or whether or not such an identifier name exists in the first place).

So if

typeof obj === 'undefined'

evaluates to true, that can mean:

  • The name 'obj' doesn't exist in the lexical environment or any outer environments,
  • The name 'obj' exists in the lexical environment chain (it's somewhere in it) and it's bound to the undefined value.
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Awesome. Thanks! In response to your first bit, what about prototype functions. For instance the method history.setState(), it seems to work testing history.setState == undefined, but I can't image the setState method is in the lexical environment if it's not supported. – CambridgeMike Nov 06 '11 at 01:35
  • @CambridgeMike My answer was about variables. With properties it's different (simpler). You can safely write `if ( obj.prop === undefined )`, although I still prefer `if ( typeof obj.prop === 'undefined' )`, just for consistency's sake. However, if the property in question is a method (which is implemented in some browsers and not implemented in some other browsers), you can even write `if ( !history.setState )` - that is how I would do it for methods. You can see this pattern in practice all over the [ES5 shim](https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js). – Šime Vidas Nov 06 '11 at 01:55
3

undefined can be overwritten by an arbitrary value. When comparing using ==, null will also return true, if undefined is undefined.

typeof obj == "undefined" is a safe way to test whether an object is undefined.

The following statements are equivalent:

var obj;
typeof obj == "undefined"; // Safe
obj === undefined;         // Provided that undefined has not been overwritten
obj === void 0;            // Void returns an `undefined` value. Also safe

The following comparisons don't produce the desired result:

var obj = null;
obj == undefined;          // True
var undefined = null;      // Overwriting undefined
obj === undefined;         // true

About jQuery: The self-invoking function accepts two formal parameters, while only one is given. As a result, the second parameter effectively holds the undefined value. Now, the second parameter is also called undefined, so inside the function, the following is true: typeof undefined == "undefined" .

(function(window, undefined){
...
})(window)
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • You forgot to mention how you can just use `obj === undefined` because any environment where `undefined` is overwritten is not an environment where your code runs or where you care about the fact your code is broken. – Raynos Nov 04 '11 at 16:41
  • @Raynos What's at the third line of my first block? If you were implying that one should not bother to not use `obj === undefined`, because it should not be overwritten: Frameworks should always take it into account. – Rob W Nov 04 '11 at 16:45
  • 2
    I personally say a framework should only run in a sensible environment. That's like saying if someone does `delete Object.prototype.toString` and `delete Object.prototype.valueOf` I should gaurd against that. (As an aside, right a framework where the unit tests pass without `toString` and `valueOf`, I doubt it can be done) – Raynos Nov 04 '11 at 16:46