Object.create()

ES5+

Creates a new object with the specified prototype object and properties.

Syntax

Object.create(proto, propertiesObject)

Parameters

proto Object | null

The object to be the prototype of the newly created object

propertiesObject Object optional

Object whose enumerable own properties specify property descriptors

Return Value

Object

A new object with the specified prototype and properties

Examples

JavaScript
const person = { greet() { return 'Hello!'; } };
const john = Object.create(person);
john.name = 'John';
console.log(john.greet());
console.log(john.name);
Output:
// 'Hello!' 'John'

📌 When to Use

Use Object.create() when you need fine-grained control over object creation with a specific prototype, implementing inheritance patterns without classes, creating objects without Object.prototype methods, or defining property descriptors at creation time.

⚠️ Common Mistakes

Forgetting that Object.create(null) creates an object without any prototype - no toString(), hasOwnProperty(), etc.

Confusing the second parameter format - it uses property descriptors like defineProperty, not simple key-value pairs.

Using Object.create() when a simple object literal or class would be clearer and more maintainable.

✅ Best Practices

Use Object.create(null) for dictionary/map objects to avoid prototype pollution and ensure safe property access.

Prefer ES6 classes for inheritance in most cases - they are more readable and widely understood.

Use Object.create() for prototype-based composition patterns or when you need objects without inherited methods.

⚡ Performance Notes

Object.create() is slightly slower than object literals ({}) because it must set up the prototype chain. However, objects created with Object.create(null) can have faster property access since there is no prototype chain to traverse. For dictionary-like objects with many lookups, Object.create(null) may offer performance benefits.

🌍 Real World Example

Safe Dictionary with No Prototype

Create a safe dictionary object that cannot be affected by prototype pollution attacks and has no inherited properties.

// Problem with regular objects as dictionaries
const unsafeDict = {};
console.log('toString' in unsafeDict); // true (inherited)
console.log('constructor' in unsafeDict); // true (inherited)

// Prototype pollution vulnerability
unsafeDict['__proto__'] = { hacked: true };
// This could affect other objects in some cases

// Safe dictionary with Object.create(null)
function createSafeDict() {
  return Object.create(null);
}

const safeDict = createSafeDict();
console.log('toString' in safeDict); // false
console.log('constructor' in safeDict); // false

// Safe to use any key, including __proto__
safeDict['__proto__'] = 'just a regular value';
safeDict['constructor'] = 'also safe';
safeDict['user_data'] = { name: 'John' };

console.log(safeDict['__proto__']); // 'just a regular value'

// Use case: User-provided keys
function cacheUserData(userId, data) {
  const cache = createSafeDict();
  cache[userId] = data; // Safe even if userId is '__proto__'
  return cache;
}

const userCache = cacheUserData('__proto__', { name: 'Alice' });
console.log(userCache['__proto__']); // { name: 'Alice' }

Related Methods