Object.getPrototypeOf()
Returns the prototype of an object, or null at the end of the prototype chain.
Object.getPrototypeOf(obj)- Added in JavaScript ES5
Parameters
| Parameter | Type | Description |
|---|---|---|
$obj | Object | The object whose prototype is to be returned. |
Return value
Object | nullThe prototype of the given object, which may be null.
Errors
Throws a TypeError if obj is null or undefined.
Changelog
- PHP ES2015A primitive argument is coerced to an object rather than throwing a TypeError, so Object.getPrototypeOf('foo') returns String.prototype instead of failing.
Object.getPrototypeOf() reads the internal [[Prototype]] link — the object that property lookups fall through to when a key is not found. It is the standard replacement for the legacy __proto__ accessor, and it works on any value that is not null or undefined.
When to reach for it
- Walking the chain to collect inherited members: loop until it returns
null. - Testing whether an object is a plain object —
Object.getPrototypeOf(x) === Object.prototypeis a common check in serializers and deep-merge helpers, and it correctly rejects class instances thattypeof x === 'object'would let through. - Detecting null-prototype objects, such as the result of Object.groupBy() or
Object.create(null).
What trips people up
An object's prototype is not its constructor. For const d = new Dog(), Object.getPrototypeOf(d) is Dog.prototype, not Dog. Comparing against the class itself always fails.
On a primitive it silently returns the wrapper prototype rather than erroring, so Object.getPrototypeOf('x') gives String.prototype. That means a passing check does not prove you were handed an object.
Example
When to use it
- Distinguish a plain object literal from a class instance before deep-merging it
- Detect a null-prototype object returned by Object.create(null) or Object.groupBy()
- Collect every inherited method by walking up to null
Frequently asked questions
Is Object.getPrototypeOf the same as __proto__?
They read the same internal slot, but Object.getPrototypeOf() is the standard API and works on null-prototype objects, whereas __proto__ is a legacy accessor inherited from Object.prototype that such objects do not have.
Why does Object.getPrototypeOf(obj) === MyClass return false?
An instance's prototype is MyClass.prototype, not MyClass itself; compare against MyClass.prototype or use instanceof.
What does it return for an object with no prototype?
It returns null, which is how you detect objects made by Object.create(null) or returned by Object.groupBy().
More examples
Printing the whole chain
Each step hops one link up until the loop reaches null, which marks the top of the chain. An array reaches Array.prototype then Object.prototype; the number 1 is boxed first, so its chain starts at Number.prototype.
function chain(value) {
const names = [];
let current = Object.getPrototypeOf(value);
while (current !== null) {
names.push(current.constructor?.name ?? "(null-prototype)");
current = Object.getPrototypeOf(current);
}
return names;
}
console.log(chain([1, 2])); // [ 'Array', 'Object' ]
console.log(chain(new Error("x"))); // [ 'Error', 'Object' ]
console.log(chain(1)); // [ 'Number', 'Object' ]A safe plain-object test
typeof reports "object" for arrays, dates and null alike, so it cannot stand alone. Checking the prototype accepts literals and null-prototype dictionaries while rejecting arrays and class instances, which is the behaviour deep-merge and serialisation code needs.
function isPlainObject(value) {
if (typeof value !== "object" || value === null) return false;
const proto = Object.getPrototypeOf(value);
return proto === Object.prototype || proto === null;
}
console.log(isPlainObject({ a: 1 })); // true
console.log(isPlainObject(Object.create(null))); // true
console.log(isPlainObject([])); // false
console.log(isPlainObject(new Date())); // false
console.log(isPlainObject(null)); // false
Discussion