Object.prototype.hasOwnProperty()
Tests whether the object has the given property as its own rather than inheriting it.
hasOwnProperty(prop)- Added in JavaScript ES3
Parameters
| Parameter | Type | Description |
|---|---|---|
$prop | string | symbol | The 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, soobj.hasOwnPropertyisundefinedand calling it throws. - Shadowing. Any object with its own
hasOwnPropertykey — trivially produced byJSON.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
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.
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")); // trueGuarding 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.
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