1451

Which is the right thing to do?

if (myObj['key'] == undefined)

or

if (myObj['key'] == null)

or

if (myObj['key'])
Zanon
  • 22,850
  • 18
  • 101
  • 110

2 Answers2

2572

Try the JavaScript in operator.

if ('key' in myObj)

And the inverse.

if (!('key' in myObj))

Be careful! The in operator matches all object keys, including those in the object's prototype chain.

Use myObj.hasOwnProperty('key') to check an object's own keys and will only return true if key is available on myObj directly:

myObj.hasOwnProperty('key')

Unless you have a specific reason to use the in operator, using myObj.hasOwnProperty('key') produces the result most code is looking for.

Dinei
  • 2,451
  • 3
  • 25
  • 49
ForYourOwnGood
  • 31,298
  • 5
  • 26
  • 27
  • 59
    The reason 'in' is considered not good is because it searches the whole prototype chain. – Nishant Dec 29 '14 at 08:28
  • 2
    and even better - if(myObj && 'key' in myObj) – pkdkk Sep 03 '15 at 13:53
  • 16
    what is wrong with searching the whole prototype chain (unless you know you don't want to for some reason)? – jononomo Nov 06 '15 at 20:52
  • 3
    @reconbot, in normal OO languages you often invoke methods defined in parent classes. What is wrong doing the same thing in js? Does it imply js prototype chains themselves are bad? Some people might actually use them. – Gherman Dec 26 '15 at 11:22
  • 4
    could have done like this Object.keys(ObjectInWhichYouwantTocheckTheKey).includes('keyInObject') :) cheers – Usman I Aug 16 '18 at 07:58
  • TypeScript doesn't seem to consider `hasOwnProperty` or `in` as a type guard. – Polv Sep 14 '19 at 16:47
  • Uncaught (in promise) TypeError: right-hand side of 'in' should be an object, got undefined – Slowaways Sep 15 '20 at 21:48
  • Should probably avoid using `hasOwnProperty` and do `Object.prototype.hasOwnProperty.call(myObj, "key");` what if your object has actual property called `hasOwnProperty` or worse, if client adds that property in? Here is more context: https://eslint.org/docs/rules/no-prototype-builtins – Ivan Procopovich Nov 13 '20 at 20:21
  • @Nishant - Is the concern performance? Because otherwise it seems like checking the whole prototype chain would be desirable... you're doing this check because you want to know whether it exists before you try accessing it, presumably, and accessing it will go through the whole prototype chain if necessary... – ArtOfWarfare Jan 02 '21 at 05:55
  • @ArtOfWarfare, yeah performance is the concern. I haven't done (heavy) OOPS in JS, so would like to hear from experts on that. I agree it might be useful depending on the use case though :-) – Nishant Jan 02 '21 at 14:47
  • 1
    @jononomo & others: It's a problem if you're using the object as a Map. If you e.g. want to make sure that an element is only once written and newer overwritten, and use `in`, you won't be able to store keys that are equal to the name of a prototype method. – SourceOverflow Jan 17 '21 at 18:04
624

You should use hasOwnProperty. For example:

myObj.hasOwnProperty('myKey');

Note: If you are using ESLint, the above may give you an error for violating the no-prototype-builtins rule, in that case the workaround is as below:

Object.prototype.hasOwnProperty.call(myObj, 'myKey');
Mustafa Ehsan Alokozay
  • 4,373
  • 2
  • 22
  • 30
typeoneerror
  • 51,338
  • 32
  • 124
  • 213
  • 3
    one problem i found with hasOwnProperty in firefox is it will return false for inherited key – Keval Malde Oct 17 '13 at 08:24
  • 264
    @maldy: isn't that the whole point of `has**Own**Property` ? – huysentruitw Jan 08 '14 at 07:54
  • 1
    for inherited key, u can check like this if(myObj.key.key) it will return true if it exists – rashidnk Mar 19 '16 at 09:12
  • 7
    ESLint rejects this as `Do not access Object.prototype method 'hasOwnProperty' from target object.` – CJBrew Sep 28 '16 at 10:56
  • 13
    @CJBrew it might be because you have the eslint flag [no-prototype-builtins](http://eslint.org/docs/rules/no-prototype-builtins) in which case you can still use it by doing `{}.hasOwnProperty.call(object, "key")` – aug Mar 03 '17 at 01:04
  • 1
    The idea of that is that if you do `myObj.hasOwnProperty()`, you are allowing myObj to intercept this call (and thus maybe mess up your logic)... However it could also be seen as an advantage that myObj can choose to do this. I personally find ESLint to be pretty anal retentive in these matters. – Stijn de Witt Apr 07 '17 at 20:28
  • 1
    Worth noting that if `myObj.myKey` has actually been declared as `undefined` (for some mad reason), then `myObj.hasOwnProperty('myKey')` will return `true`. – Headbank Feb 28 '19 at 15:14
  • 14
    I'm gonna leaves this here for anyone that will wonder why ESLint is complaining https://eslint.org/docs/rules/no-prototype-builtins – JanithaR May 16 '19 at 09:12
  • that's an antipattern imo, **own** property should just be used for that level. – GeorgeWL Jul 31 '19 at 09:20