23

The most bulletproof way of checking if an object has a certain key is:

Object.prototype.hasOwnProperty.call(obj, key)

This provides certain guarantees: it will only evaluate to true if key is a direct property of obj, and it will work even if obj doesn't have the usual Object as its prototype (for example, if it was created with const obj = Object.create(null)).

But it's a mouthful.

Is there any new syntax/method in ES6 or higher (including polyfillable or Babel-compilable 'proposals') that gives the same guarantees, but in a nicer, more readable way?

callum
  • 34,206
  • 35
  • 106
  • 163
  • Why not just alias it with a variable? i.e. `const iHaz = Object.prototype.hasOwnProperty` then use it like `const iDoHaz = iHaz.call(obj, key)` – Joseph Jul 20 '17 at 13:11
  • Well, given that you almost never need to use this, what's the problem? – Bergi Jul 20 '17 at 13:13
  • `const has = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)` is the alias I typically use. – zzzzBov Jul 20 '17 at 13:16
  • Yeah I usually write an alias. I just want to know if there's a nicer way available now, because if there is, then I don't have to keep writing aliases – callum Jul 20 '17 at 13:19
  • 1
    The only ES Next feature I can think of that would shorten this at all is the bind operator, and its not much of a win here: `obj::Object.prototype.hasOwnProperty(key)`. – Jared Smith Jul 20 '17 at 13:20
  • FWIW they've added `getOwnPropertyNames`, but it's still ugly when used to check for a single prop: `Object.getOwnPropertyNames(obj).includes(key)`. It would be nice if there was a neater way to check for a single prop, like `Object.has(obj, key)` – callum Jul 20 '17 at 13:21
  • 1
    @callum actually I guess you could combine that with Bergi's answer and get `obj::({}).hasOwnProperty(key)` but that's a lose in terms of readability and I'm not sure how the precedence works out or even if the precedence for the bind operator proposal has stabilized. – Jared Smith Jul 20 '17 at 13:23

2 Answers2

13

Update: Object.hasOwn(obj, key) is part of ES2022.


I'm not aware of any syntactical sugar for this. But you shouldn't need to use this very often1, so writing it out occasionally shouldn't be too bad. An equivalent shorter version would be

({}).hasOwnProperty.call(obj, key)

If you really need to use it more often, just define a helper function:

const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);

1: In most cases, you can omit the check, use in instead, or should be using a Map with its comfortable has method.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
4

Object.hasOwn was added to Object standard API. It is now supported on all major browsers.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Fabiano Taioli
  • 5,270
  • 1
  • 35
  • 49