Categories
javascript object object-property undefined

Detecting an undefined object property

3131

What’s the best way of checking if an object property in JavaScript is undefined?

2

  • Look for recent answers in this thread. In ‘modern’ javascript, consider using the in operator:'key' in obj ? 'obj has key property' : 'obj does not have key property' `

    Aug 23, 2021 at 16:19

  • I’m open to picking a new ‘correct’ answer if you have one in mind that covers the old way as completely as the current one and also addresses more modern options.

    Aug 24, 2021 at 20:59

2883

The usual way to check if the value of a property is the special value undefined, is:

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

To check if an object does not actually have such a property, and will therefore return undefined by default when you try to access it:

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

To check if the value associated with an identifier is the special value undefined, or if that identifier has not been declared:

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

Note: this last method is the only way to refer to an undeclared identifier without an early error, which is different from having a value of undefined.

In versions of JavaScript prior to ECMAScript 5, the property named “undefined” on the global object was writeable, and therefore a simple check foo === undefined might behave unexpectedly if it had accidentally been redefined. In modern JavaScript, the property is read-only.

However, in modern JavaScript, “undefined” is not a keyword, and so variables inside functions can be named “undefined” and shadow the global property.

If you are worried about this (unlikely) edge case, you can use the void operator to get at the special undefined value itself:

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

10

  • 10

    if something is null the it is defined (as null), but you can conjugate the too checks. The annoying detail of the above code is that you can’t define a function to check it, well you can define the function… but try to use it.

    – neu-rah

    Jun 25, 2012 at 19:20

  • 6

    @neu-rah why can’t you write a function? why wouldn’t something like this work? It seems to work for me. Is there a case I’m not considering? jsfiddle.net/djH9N/6

    – Zack

    Sep 24, 2012 at 19:01

  • 8

    @Zack Your tests for isNullorUndefined did not consider the case where you call isNullOrUndefined(f) and f is undeclared (i.e. where there is no “var f” declaration).

    – pnkfelix

    Feb 15, 2013 at 15:08

  • 139

    Blah, thousands of votes now. This is the worst possible way to do it. I hope passers-by see this comment and decide to check… ahem… other answers.

    – Ry-

    May 14, 2014 at 3:05


  • 22

    You can just use obj !== undefined now. undefined used to be mutable, like undefined = 1234 what would cause interesting results. But after Ecmascript 5, it’s not writable anymore, so we can use the simpler version. codereadability.com/how-to-check-for-undefined-in-javascript

    Mar 15, 2016 at 20:50

966

I believe there are a number of incorrect answers to this topic. Contrary to common belief, “undefined” is not a keyword in JavaScript and can in fact have a value assigned to it.

Correct Code

The most robust way to perform this test is:

if (typeof myVar === "undefined")

This will always return the correct result, and even handles the situation where myVar is not declared.

Degenerate code. DO NOT USE.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Additionally, myVar === undefined will raise an error in the situation where myVar is undeclared.

17

  • 23

    in addition to Marks comments, I don’t get this: “myVar === undefined will raise an error in the situation where myVar is undeclared.” – why is this bad? Why would I not want to have an error if I’m referencing undeclared variables?

    – eis

    Aug 20, 2013 at 15:12

  • 5

    Also keep in mind you can always do void 0 to get the value that undefined points to. So you can do if (myVar === void 0). the 0 isn’t special, you can literally put any expression there.

    – Claudiu

    Oct 3, 2013 at 17:45

  • 33

    In modern browsers (FF4+, IE9+, Chrome unknown), it’s no longer possible to modify undefined. MDN: undefined

    Feb 7, 2014 at 14:09

  • 11

    This answer is incorrect as well. The question was about undefined object properties, not undefined variables. There is a significant difference. It is, for example, perfectly reasonable to do if (obj.field === undefined). I think the risk of someone doing var undefined = false; is overrated. You will have to program unreasonably defensive if you want to protect against all such kinds of side effects caused by poor programming.

    – Zero3

    Dec 15, 2015 at 15:38

  • 9

    Funny that people suggest these silly and error-prone hacks to avoid a shadowed undefined (which could only be done by a terrible developer), yet they blithely use other global identifiers that could also have been shadowed. Bizarre. Just bizarre.

    – user8897421

    Dec 18, 2017 at 13:39

270

Despite being vehemently recommended by many other answers here, typeof is a bad choice. It should never be used for checking whether variables have the value undefined, because it acts as a combined check for the value undefined and for whether a variable exists. In the vast majority of cases, you know when a variable exists, and typeof will just introduce the potential for a silent failure if you make a typo in the variable name or in the string literal 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

So unless you’re doing feature detection², where there’s uncertainty whether a given name will be in scope (like checking typeof module !== 'undefined' as a step in code specific to a CommonJS environment), typeof is a harmful choice when used on a variable, and the correct option is to compare the value directly:

var foo = …;

if (foo === undefined) {
    ⋮
}

Some common misconceptions about this include:

  • that reading an “uninitialized” variable (var foo) or parameter (function bar(foo) { … }, called as bar()) will fail. This is simply not true – variables without explicit initialization and parameters that weren’t given values always become undefined, and are always in scope.

  • that undefined can be overwritten. It’s true that undefined isn’t a keyword, but it is read-only and non-configurable. There are other built-ins you probably don’t avoid despite their non-keyword status (Object, Math, NaN…) and practical code usually isn’t written in an actively malicious environment, so this isn’t a good reason to be worried about undefined. (But if you are writing a code generator, feel free to use void 0.)

With how variables work out of the way, it’s time to address the actual question: object properties. There is no reason to ever use typeof for object properties. The earlier exception regarding feature detection doesn’t apply here – typeof only has special behaviour on variables, and expressions that reference object properties are not variables.

This:

if (typeof foo.bar === 'undefined') {
    ⋮
}

is always exactly equivalent to this³:

if (foo.bar === undefined) {
    ⋮
}

and taking into account the advice above, to avoid confusing readers as to why you’re using typeof, because it makes the most sense to use === to check for equality, because it could be refactored to checking a variable’s value later, and because it just plain looks better, you should always use === undefined³ here as well.

Something else to consider when it comes to object properties is whether you really want to check for undefined at all. A given property name can be absent on an object (producing the value undefined when read), present on the object itself with the value undefined, present on the object’s prototype with the value undefined, or present on either of those with a non-undefined value. 'key' in obj will tell you whether a key is anywhere on an object’s prototype chain, and Object.prototype.hasOwnProperty.call(obj, 'key') will tell you whether it’s directly on the object. I won’t go into detail in this answer about prototypes and using objects as string-keyed maps, though, because it’s mostly intended to counter all the bad advice in other answers irrespective of the possible interpretations of the original question. Read up on object prototypes on MDN for more!

¹ unusual choice of example variable name? this is real dead code from the NoScript extension for Firefox.
² don’t assume that not knowing what’s in scope is okay in general, though. bonus vulnerability caused by abuse of dynamic scope: Project Zero 1225
³ once again assuming an ES5+ environment and that undefined refers to the undefined property of the global object.

13

  • @BenjaminGruenbaum True but completely misleading. Any non-default context can define its own undefined, hiding the default one. Which for most practical purposes has the same effect as overwriting it.

    – blgt

    Mar 25, 2014 at 14:32

  • 26

    @blgt That’s paranoid and irrelevant for anything practical. Every context can override console.log, redefine Array prototype methods, and even override Function.prototype.call` hooking, and altering every time you call a function in JavaScript. Protecting against this is very paranoid and rather silly. Like I (and minitech) said, you can use void 0 to compare against undefined but again – that’s silly and overkill.

    Mar 25, 2014 at 14:41

  • 24

    I wish I had more than one upvote to give. This is the most correct answer. I really wanna stop seeing typeof something === "undefined") in code.

    Feb 20, 2018 at 19:37

  • 5

    This really should be the accepted answer. It is the most thorough and up-to-date.

    Apr 10, 2019 at 20:40

  • 1

    Any non-default context can also overwrite, say, Math, or Object, or setTimeout, or literally anything that you expect to find in the global scope by default.

    – CherryDT

    Mar 17, 2020 at 21:21