Skip to main content

Object.create()

Object.create() is one of the core methods for working with prototypes in JavaScript: it creates a new object whose prototype, that is, what it inherits from, you specify by hand. An optional second argument defines own properties through descriptors right away.

Theory

TL;DR

  • Syntax: Object.create(proto, [propertiesObject]).
  • proto becomes the new object's [[Prototype]], which you can verify with Object.getPrototypeOf().
  • The second argument defines own properties as descriptors, exactly like Object.defineProperty().
  • Object.create(null) creates an object with no prototype at all, handy as a dictionary.
  • It is the simplest form of prototypal inheritance without class and constructors.
  • The new object does not copy the prototype's properties, it only links to them.

Quick example

javascript
const user = { sayHi() { console.log(`Hi, ${this.name}!`); } }; const alice = Object.create(user); // an object inheriting from user alice.name = 'Alice'; alice.sayHi(); // "Hi, Alice!"

Here user is the prototype ([[Prototype]]) of alice. The object alice has no sayHi of its own, it inherits it through the prototype.

Syntax and parameters

javascript
Object.create(proto, [propertiesObject])
ParameterDescription
protoThe object that becomes the new object's prototype (or null)
propertiesObject (optional)Extra own properties, in descriptor form

You can verify the result like this:

javascript
console.log(Object.getPrototypeOf(alice) === user); // true

Object.create() literally builds a new object whose internal [[Prototype]] is user.

An object with no prototype

javascript
const data = Object.create(null); data.a = 1; console.log(data); // { a: 1 } console.log(Object.getPrototypeOf(data)); // null console.log(data.toString); // undefined

Such an object inherits nothing at all, not even toString or hasOwnProperty. It is used as a clean dictionary (a map object) where keys come from outside and must not collide with Object.prototype method names. The only downside: key checks have to go through Object.hasOwn(data, key) or 'a' in data.

The second argument: property descriptors

Properties can be defined with attributes straight away, as in Object.defineProperty():

javascript
const person = Object.create({}, { name: { value: 'Alice', writable: false, enumerable: true }, age: { value: 25, writable: true } }); console.log(person.name); // "Alice" person.name = 'Bob'; // does not change the value console.log(person.name); // "Alice"

The second parameter accepts the same attributes: value, writable, enumerable, configurable, plus get and set. Remember that omitted attributes default to false here too, so age in the example will not show up in Object.keys().

Prototypal inheritance without classes

The most direct way to wire up inheritance by hand:

javascript
const Animal = { eat() { console.log('I eat'); } }; const Dog = Object.create(Animal); Dog.bark = function() { console.log('Woof!'); }; Dog.eat(); // "I eat", inherited from Animal Dog.bark(); // "Woof!", its own method

The same approach replaces class once instance creation moves into an init method:

javascript
const UserProto = { init(name) { this.name = name; return this; }, greet() { console.log(`Hi, ${this.name}`); } }; const user = Object.create(UserProto).init('Alice'); user.greet(); // "Hi, Alice"

This style is common in functional OOP: no classes, but inheritance through the prototype.

Summary:

What it doesExampleResult
Creates an object with a given prototypeObject.create(proto)A new object whose [[Prototype]] = proto
Creates an object with no prototypeObject.create(null)A "clean" object without toString or hasOwnProperty
Defines properties with attributesObject.create({}, { key: { value: 1 } })The equivalent of defineProperty()
Implements inheritanceconst child = Object.create(parent)child inherits the properties of parent

Common mistakes

  • Confusing a prototype with a copy. Object.create(proto) copies nothing: change proto later and the descendant sees the change.
  • Looking for inherited keys in Object.keys(). It lists own properties only, while for...in does walk the prototype chain, so loops need Object.hasOwn().
  • Calling Object.prototype methods on an Object.create(null) object. data.hasOwnProperty('a') throws TypeError; the correct form is Object.hasOwn(data, 'a') or Object.prototype.hasOwnProperty.call(data, 'a').
  • Forgetting the false defaults in the second argument. A property created through propertiesObject without explicit attributes is neither writable nor enumerable.
  • Writing to an inherited property and expecting the prototype to change. The assignment creates an own property on the descendant and simply shadows the prototype's one instead of modifying it.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.