What is Object.setPrototypeOf()?
The Object.setPrototypeOf() static method sets the prototype (i.e., the internal [[Prototype]] property) of a specified object to another object or null. This method is part of ECMAScript 2015 (ES6) and represents the modern, standard way to change an object's prototype after it has been created.
In JavaScript, objects have an internal property called [[Prototype]] that points to another object from which they inherit properties and methods. This prototype chain forms the basis of JavaScript's inheritance model, allowing objects to share functionality without duplicating code.
Quick Example
const parent = {
greet() {
return "Hello from parent!";
}
};
const child = { name: "Child" };
Object.setPrototypeOf(child, parent);
console.log(child.greet()); // "Hello from parent!"
Understanding prototype inheritance is essential for mastering JavaScript's object model and writing efficient, maintainable code.
According to the MDN Web Docs, this method has been available since ES6 and is the recommended approach for prototype manipulation.
obj parameter
The object whose prototype is to be set. This object will have its [[Prototype]] property modified.
prototype parameter
The object's new prototype - either another object or null. Setting to null breaks the prototype chain.
Return value
Returns the modified object, enabling method chaining for convenience.
setPrototypeOf() vs. Other Approaches
The proto Approach (Deprecated)
Setting or reading the prototype with obj.__proto__ is considered outdated and moved to "Annex B" of the JavaScript standard (optional for non-browser environments). Always prefer Object.setPrototypeOf() for new code.
// Deprecated approach (avoid)
obj.__proto__ = newPrototype;
// Modern standard approach (preferred)
Object.setPrototypeOf(obj, newPrototype);
Using Object.create() for Better Performance
For creating objects with a specific prototype, Object.create() is generally preferred because it sets the prototype at creation time, allowing JavaScript engines to optimize property access.
// Preferred: Set prototype at creation time
const child = Object.create(parent);
child.name = "Child";
// Avoid: Change prototype after creation (performance impact)
const child = { name: "Child" };
Object.setPrototypeOf(child, parent);
As noted by JavaScript.info, the modern methods to get and set prototypes are Object.getPrototypeOf(obj) and Object.setPrototypeOf(obj, proto), which replaced the deprecated __proto__ property.
For additional context on JavaScript's object creation patterns, see our guide to deep copy techniques and how they relate to object manipulation.
Error Handling and Edge Cases
TypeError Thrown When:
- obj is undefined or null - The method requires a valid object reference
- obj is non-extensible - Cannot modify objects created with
Object.preventExtensions() - obj is an immutable prototype exotic object - Such as
Object.prototypeorwindow - prototype is not an object or null - String, number, or other primitives are not valid prototypes
// These will throw TypeError:
Object.setPrototypeOf(Object.prototype, {}); // Immutable prototype
Object.setPrototypeOf(obj, "string"); // Invalid prototype type
According to MDN Web Docs, the method throws TypeError when these conditions are not met.
Understanding these error conditions helps when working with strict mode and other JavaScript best practices that catch common mistakes early.
Best Practices and Modern Alternatives
When to Use setPrototypeOf()
- Legacy code migration - When converting constructor function patterns to modern inheritance
- Dynamic inheritance - When objects genuinely need to change prototypes at runtime
- Mixin-based composition - When combining behaviors from multiple sources dynamically
- Testing scenarios - When mocking object relationships in tests
When to Avoid setPrototypeOf()
- Performance-critical code - Hot paths in applications
- Object creation in loops - Creates repeated performance penalties
- New code with fixed inheritance - Use
Object.create()or class syntax instead
Modern Alternatives
Class Syntax (for static inheritance):
class Parent { greet() { return "Hello!"; } }
class Child extends Parent {}
Object.create() (for prototype at creation):
const child = Object.create(parent);
Factory with closures (composition over inheritance):
const withGreeting = (obj) => ({
...obj,
greet() { return "Hello!"; }
});
As documented by MDN Web Docs, if you are concerned about performance, you should avoid setting the [[Prototype]] of an object and instead create a new object with the desired prototype using Object.create().
These patterns align with modern JavaScript development practices, including proper hoisting understanding and clean code principles.
Frequently Asked Questions
Is Object.setPrototypeOf() the same as __proto__?
Functionally similar, but setPrototypeOf() is the modern standard method. The __proto__ property is deprecated (in Annex B) and should be avoided in new code.
Why is setPrototypeOf() slow?
JavaScript engines optimize property access based on fixed prototypes. Changing prototypes invalidates these optimizations, requiring the engine to fall back to slower property lookup mechanisms.
Can I set an object's prototype to null?
Yes. Setting prototype to null breaks the prototype chain, making the object a 'bare' object without inherited properties from Object.prototype.
Does setPrototypeOf() affect existing properties?
No. The method only changes the prototype reference. Existing properties remain unchanged. Only property lookups through inheritance are affected.
What browsers support Object.setPrototypeOf()?
All modern browsers: Chrome, Firefox, Safari, Edge, and Opera. Support dates back to September 2015.
Browser Support
Object.setPrototypeOf() is widely supported across all modern browsers:
- Chrome (v+)
- Firefox (v+)
- Safari (v+)
- Edge (v+)
- Opera (v+)
This feature has been available since September 2015 and is considered baseline widely available.
Summary
Object.setPrototypeOf() is the modern standard method for changing an object's prototype at runtime. While powerful, its use should be carefully considered due to performance implications. For most use cases, prefer creating objects with the correct prototype from the start using Object.create() or class syntax.
Understanding prototype manipulation complements other JavaScript fundamentals like null handling, request handling, and proper attributes management in your applications.