Object.setPrototypeOf()

Sets the prototype of an existing object to another object or to null.

Signature
Object.setPrototypeOf(obj, prototype)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$objObjectThe object which is to have its prototype set.
$prototypeObject | nullThe object's new prototype: an object, or null.

Return value

ObjectThe specified object, obj.

Errors

Throws a TypeError if obj is null or undefined, if obj is non-extensible or an immutable prototype exotic object, or if prototype is neither an object nor null; no error is thrown when the new prototype equals the existing one.

Object.setPrototypeOf() rewires an object's [[Prototype]] after the object already exists. It works, it is standard, and it is almost always the wrong tool.

Why it is discouraged

Every engine optimises property access by assuming an object's shape and prototype are stable. Mutating the prototype invalidates the inline caches for that object and for any code that has touched it, and the deoptimisation is permanent for the affected code paths. Creating an object with the right prototype from the start avoids all of it:

// slow
const o = {};
Object.setPrototypeOf(o, parent);

// fast — same result
const o = Object.create(parent);

When it is still the right call

  • Re-attaching a class prototype to data that crossed a boundary that strips it, such as JSON.parse() output or a structured-clone result. There is no object to build from scratch, only one to repair.
  • Extending built-ins like Error when a transpiler target has broken the chain set up by super().
  • Object.setPrototypeOf(obj, null) to turn an existing object into a bare dictionary, so that keys like constructor or __proto__ cannot collide with inherited members.

Outside those repair cases, prefer Object.create(), a class, or a factory function.

Example

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

When to use it

  • Restore class methods on plain objects revived from JSON.parse
  • Turn an existing object into a null-prototype dictionary to avoid key collisions
  • Repair a broken prototype chain when subclassing a built-in under an old transpiler target

Frequently asked questions

Why is Object.setPrototypeOf considered slow?

Mutating an object's prototype invalidates the engine's inline caches for that object and any code that has already accessed it, permanently deoptimising those property lookups; Object.create() gives the same result with no penalty.

When should I use setPrototypeOf instead of Object.create?

Only when the object already exists and you cannot recreate it, such as re-attaching a class prototype to the result of JSON.parse() or a structured clone.

Why does setPrototypeOf throw a TypeError on my object?

Either the object is non-extensible (frozen or sealed), it is an immutable prototype exotic object such as Object.prototype, or the second argument is a primitive rather than an object or null.

More examples

Reviving class instances from JSON

JSON.parse() always produces plain objects, so the parsed data has the fields but none of the behaviour. Re-pointing the prototype restores the methods and makes instanceof pass, without re-running the constructor.

Example · javascript
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  length() {
    return Math.hypot(this.x, this.y);
  }
}

const revived = JSON.parse('{"x":3,"y":4}');
console.log(typeof revived.length);        // "undefined"

Object.setPrototypeOf(revived, Point.prototype);
console.log(revived.length());             // 5
console.log(revived instanceof Point);      // true

Turning an object into a bare dictionary

With the prototype removed, every inherited member disappears and only real data remains, so a key named toString can no longer be confused with the inherited method. Note that Object.hasOwn() still works on such an object while counts.hasOwnProperty() would throw.

Example · javascript
const counts = { toString: 3, constructor: 1 };
console.log(typeof counts.valueOf);        // "function" — inherited

Object.setPrototypeOf(counts, null);
console.log(counts.valueOf);               // undefined
console.log(counts.toString);              // 3 — own value, no longer shadowing
console.log(Object.keys(counts));          // [ 'toString', 'constructor' ]
console.log(Object.hasOwn(counts, "toString")); // true

Discussion

  • Be the first to comment on this lesson.