Object.prototype.hasOwnProperty()

Tests whether the object has the given property as its own rather than inheriting it.

Signature
hasOwnProperty(prop)
  • Added in JavaScript ES3

Parameters

ParameterTypeDescription
$propstring | symbolThe name or symbol of the property to test.

Return value

booleantrue if the object has the specified property as its own property, otherwise false.

Errors

Throws a TypeError if called on null or undefined, or if the object's own hasOwnProperty key shadows the method with a non-callable value.

Changelog

  • PHP ES2022Object.hasOwn() was added as a static equivalent that cannot be shadowed and works on null-prototype objects; prefer it in new code.

hasOwnProperty() asks whether a key belongs to the object itself rather than to something on its prototype chain. It is the classic guard inside a for...in loop, where inherited enumerable keys would otherwise be visited.

Two ways it breaks

Because it is reached by an ordinary property lookup on the object, the call fails whenever that lookup does not find the real method:

  • Null-prototype objects. Object.create(null) and the result of Object.groupBy() inherit nothing, so obj.hasOwnProperty is undefined and calling it throws.
  • Shadowing. Any object with its own hasOwnProperty key — trivially produced by JSON.parse() on untrusted input — hijacks or breaks the call.

The safe call is Object.prototype.hasOwnProperty.call(obj, key), and since ES2022 the readable form is Object.hasOwn(obj, key). New code should use the latter; this method remains for compatibility and for engines older than 2022.

Versus the in operator

in searches the entire chain, so 'toString' in obj is true for any ordinary object. hasOwnProperty() stops at the object itself.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Guard a for...in loop so inherited enumerable keys are skipped
  • Support environments that predate Object.hasOwn()
  • Check for an array index that has actually been assigned rather than left as a hole

Frequently asked questions

Why does hasOwnProperty throw "is not a function"?

The object has no prototype, typically from Object.create(null) or Object.groupBy(), so it inherits nothing; call Object.hasOwn(obj, key) or Object.prototype.hasOwnProperty.call(obj, key) instead.

What is the difference between hasOwnProperty and the in operator?

hasOwnProperty() checks only the object's own properties, while in returns true for inherited properties as well.

Should I still use hasOwnProperty in new code?

Prefer Object.hasOwn(), which has been available since ES2022 and cannot be shadowed or broken by a null prototype; keep this method only for older runtimes.

More examples

The shadowing failure and the safe call

The first line consults the object's own method and gets a confident lie. Borrowing the real implementation from Object.prototype with .call() bypasses the object's own keys entirely, which is also the only form that works on the null-prototype object where the method does not exist at all.

Example · javascript
const hostile = {
  hasOwnProperty() {
    return false;
  },
  token: "abc",
};

console.log(hostile.hasOwnProperty("token"));                         // false — wrong
console.log(Object.prototype.hasOwnProperty.call(hostile, "token"));  // true
console.log(Object.hasOwn(hostile, "token"));                         // true

const bare = Object.create(null);
bare.token = "abc";
console.log(typeof bare.hasOwnProperty);                              // "undefined"
console.log(Object.prototype.hasOwnProperty.call(bare, "token"));     // true

Guarding a for...in loop

for...in visits enumerable inherited keys, so shared appears in the unguarded list. The guard filters it out and reproduces exactly what Object.keys() returns, which is why Object.keys() or Object.entries() is usually the simpler choice.

Example · javascript
const proto = { shared: "from prototype" };
const config = Object.create(proto);
config.host = "localhost";
config.port = 8080;

const all = [];
const own = [];
for (const key in config) {
  all.push(key);
  if (Object.prototype.hasOwnProperty.call(config, key)) own.push(key);
}

console.log(all);   // [ 'host', 'port', 'shared' ]
console.log(own);   // [ 'host', 'port' ]
console.log(Object.keys(config)); // [ 'host', 'port' ]

Discussion

  • Be the first to comment on this lesson.