JAVASCRIPT • OBJECT-ORIENTED PROGRAMMING (INTRO)

Object.create — Use Object.create conceptually (intro)

Learn how JavaScript lets you build new objects directly from existing ones using prototype-based inheritance.

Historical Context & Motivation

Most programming languages you may have heard of — like Java or Python — use classes as blueprints to create objects. JavaScript took a different road. When Brendan Eich designed the language in 1995, he chose a prototype-based approach, meaning objects are created directly from other objects rather than from abstract templates. This design choice was inspired by a lesser-known language called Self, and it gives JavaScript a unique flexibility that can feel strange at first but is incredibly powerful once you understand it.

For years, JavaScript developers used constructor functions and the new keyword to create objects. While this worked, it often confused people because it tried to mimic classical inheritance without truly being classical. The community needed a cleaner, more explicit way to create objects that embraced JavaScript's true nature. That need led to Object.create, introduced in ECMAScript 5 (2009), which lets you create a new object and directly specify its prototype — the object it inherits from.

1986
Self Language Created
Researchers at Xerox PARC created Self, a prototype-based language where objects inherit directly from other objects — no classes needed.
1995
JavaScript Is Born
Brendan Eich created JavaScript in just 10 days at Netscape. He adopted prototype-based inheritance from Self, making it the core of how JS objects relate to each other.
2006
Douglas Crockford Advocates Object.create
In his influential book JavaScript: The Good Parts, Crockford proposed a simple function to create objects from prototypes, foreshadowing the official method.
2009
ECMAScript 5 Ships Object.create
Object.create() becomes an official part of the language, giving developers a clean, explicit way to set up prototype chains.
2015
ES6 Classes Arrive
ES6 introduced the class keyword, but under the hood it still uses prototypes. Understanding Object.create helps you see what classes really do.

So the big question this lesson answers is: How can you create a new object that automatically shares behavior from an existing object, without needing a class or constructor? That is exactly what Object.create does.

Core Principles & Definitions

Before diving into code, let's lock down a few ideas. In JavaScript, every object can have a hidden link to another object — this link is called its prototype. When you ask an object for a property it doesn't own, JavaScript follows that link and checks the prototype. If the prototype doesn't have it either, JavaScript follows the prototype's prototype, and so on. This chain of links is called the prototype chain. The method Object.create(proto) creates a brand-new, empty object whose prototype is set to proto.

1

Prototype

An object that another object delegates to when it can't find a property on itself. Think of it as a fallback reference.
2

Prototype Chain

The sequence of linked prototypes JavaScript searches through when looking up a property. It ends at null.
3

Object.create(proto)

A built-in method that returns a new, empty object whose internal prototype is set to proto. No constructor function is needed.
4

Own Properties vs. Inherited

Own properties live directly on the object. Inherited properties are found by walking up the prototype chain.
5

Delegation, Not Copying

Object.create does not copy properties. The child delegates to the parent at runtime, keeping a live link.
✦ KEY TAKEAWAY
Imagine you share a family Netflix account. You don't have every movie downloaded on your phone — instead, your phone delegates to the family account when you search for something. Object.create works the same way: the new object doesn't copy all the properties — it just knows where to look them up when needed. If the family account adds a new show, you see it immediately because the link is live.

Visual Explanation — The Prototype Chain

The animal object holds shared methods like speak() and eat(). The dog object was created with Object.create(animal), so it has its own breed property but delegates method calls up the dashed arrow to animal.

Notice that dog never received a copy of speak(). When you call dog.speak(), JavaScript first checks dog itself. Finding nothing, it follows the hidden [[Prototype]] link (the dashed arrow) up to animal, where speak() lives. This process is called delegation — the child object delegates the work to its prototype. If animal didn't have it either, JS would keep climbing until it reaches null (the end of the chain) and then return undefined.

How Object.create Works Under the Hood

The syntax for Object.create is straightforward. It takes one required argument — the object that should become the new object's prototype — and one optional argument for defining additional properties. For this introductory lesson, we'll focus on the first argument.

BASIC SYNTAX
const child = Object.create( prototypeObject );
prototypeObject — any existing object (or null). The returned child is a new, empty object whose internal [[Prototype]] points to prototypeObject.

Let's trace what happens in memory when this code runs. First, JavaScript allocates a fresh, empty object — no properties of its own. Then it sets the internal [[Prototype]] slot of this new object to reference prototypeObject. That's it — no constructor function is invoked, no new keyword is needed. The result is a clean, direct prototype link.

Adding Own Properties After Creation

Because the object starts empty, you'll usually assign own properties right after creating it. These are properties that belong only to this specific object, not shared through the prototype. Here's a quick pattern:

COMMON PATTERN
const dog = Object.create(animal); dog.breed = "Labrador"; dog.name = "Max";
breed and name are own properties of dog. Methods like speak() and eat() are inherited from animal.

Property Shadowing

What if dog defines a property with the same name as one on animal? For example, if you write dog.type = "dog", JavaScript won't modify animal.type. Instead, it creates a new own property on dog that shadows (hides) the inherited one. This is called property shadowing and it means each object can customize behavior without affecting the prototype.

Object.create vs. Other Object Creation Methods

JavaScript gives you several ways to create objects, and it's important to understand how Object.create compares to the alternatives. The diagram below maps three common approaches side by side, showing what each produces in terms of own properties and prototype links.

Comparison of three common object creation patterns. Object.create stands out because you choose exactly which object becomes the prototype, giving you fine-grained control over the inheritance chain.
Comparison of JavaScript object creation methods
FeatureObject LiteralObject.createConstructor + new
Custom prototype?No — always Object.prototypeYes — you chooseYes — via .prototype property
Runs a function?NoNoYes — the constructor
Starts empty?No — has defined propertiesYes — truly emptyNo — constructor sets properties
Best forQuick one-off objectsSetting up inheritance chainsCreating many similar objects

Worked Example — Building a Vehicle Hierarchy

Let's walk through a complete example step by step. We'll create a vehicle prototype and then use Object.create to build a car that inherits from it.

Creating a Car from a Vehicle Prototype
1
Step 1 — Define the Prototype ObjectWe start by creating a plain object called vehicle that holds shared properties and methods. This object will act as the prototype for all vehicles. const vehicle = { wheels: 4, start() { return "Engine started!"; }, describe() { return this.make + " " + this.model; } };
vehicle has wheels, start(), and describe()
2
Step 2 — Create a New Object with Object.createNow we call Object.create(vehicle) to make a new object whose prototype is vehicle. At this point, car is an empty object. const car = Object.create(vehicle);
car → empty, prototype → vehicle
3
Step 3 — Add Own PropertiesWe give car its own unique data. These properties belong only to car and won't affect vehicle. car.make = "Toyota"; car.model = "Camry"; car.year = 2024;
car now owns make, model, year
4
Step 4 — Test Inherited MethodsCalling car.start() works even though car doesn't have its own start method. JavaScript delegates up the prototype chain to vehicle. car.start(); // "Engine started!"
"Engine started!" — inherited from vehicle
5
Step 5 — Test describe() with 'this'Here's the cool part: car.describe() calls vehicle.describe(), but this inside the method refers to car, not vehicle. So it reads car.make and car.model. car.describe(); // "Toyota Camry"
"Toyota Camry" — this binds to the calling object
💡 Why 'this' Matters
Even though describe() is defined on vehicle, when called as car.describe(), the this keyword refers to car. This means inherited methods can read the child's own properties — making shared methods reusable across many different objects.

Strengths & Limitations of Object.create

Like any tool, Object.create has its sweet spots and its rough edges. Understanding both will help you choose the right approach when writing real code.

Strengths and limitations of Object.create
Strengths ✅Limitations ⚠️
Explicit and readable — you can clearly see which object is the prototype.The created object starts empty, so you must manually add every own property.
No constructor function required — simpler mental model.No built-in way to run initialization logic (like a constructor does).
Works with any object, including plain objects and null.Sharing mutable data (arrays, nested objects) on the prototype can cause unexpected side effects.
Great for building prototype chains for delegation.Less familiar to developers coming from class-based languages like Java or C++.
Helps you understand what ES6 classes do under the hood.For large projects, ES6 class syntax is often preferred for consistency.
✦ KEY TAKEAWAY
Think of Object.create like getting a blank phone case that clips onto a specific phone model. The case (new object) starts with nothing on it, but it's shaped to fit that particular phone (its prototype). You can decorate the case however you like (add own properties), and the phone's built-in features (inherited methods) are always accessible through it. The tradeoff? You have to add the decorations yourself — they don't come pre-applied.

Connection to ES6 Classes and Advanced Patterns

In 2015, JavaScript introduced the class keyword with ES6. Many beginners assume that classes and Object.create are completely different systems. In reality, ES6 classes are syntactic sugar over the same prototype mechanism. When you write class Dog extends Animal, JavaScript uses Object.create behind the scenes to link Dog.prototype to Animal.prototype.

Object.create vs. ES6 classes
FeatureObject.create (this lesson)ES6 class (advanced)
Syntax styleFunctional — just method callsDeclarative — class keyword
ConstructorNone (add properties manually)constructor() method runs automatically
InheritanceObject.create(proto)extends ParentClass
Under the hoodDirect prototype linkageAlso uses prototype linkage!
When to useLearning prototypes, simple delegationLarger apps, team projects, familiar syntax

Understanding Object.create now gives you a huge advantage later. When you encounter ES6 classes, you'll know that extends is just calling Object.create internally. You'll also be able to debug tricky inheritance issues by inspecting the prototype chain directly. In advanced patterns like Object Linking to Other Objects (OLOO), developers use Object.create exclusively — no classes, no constructors — to build clean, composable code.

Practice Problems

PROBLEM 1 — CONCEPTUAL
When you call Object.create(someObj), does the new object receive copies of someObj's properties? Explain what actually happens.
PROBLEM 2 — BASIC CALCULATION
Given the following code, what does puppy.sound return? Explain your reasoning. const pet = { sound: "generic noise", legs: 4 }; const puppy = Object.create(pet); puppy.sound = "woof";
PROBLEM 3 — INTERMEDIATE
Predict the output of each console.log statement below and explain why: const shape = { sides: 0, describe() { return "I have " + this.sides + " sides."; } }; const triangle = Object.create(shape); triangle.sides = 3; const square = Object.create(shape); square.sides = 4; console.log(triangle.describe()); console.log(square.describe()); console.log(shape.describe());
PROBLEM 4 — APPLIED
You're building a simple game. Create a character prototype with properties health: 100 and a method takeDamage(amount) that subtracts amount from this.health. Then create a warrior using Object.create that has name: "Aria" and weapon: "sword". What is warrior.health after calling warrior.takeDamage(25)?
PROBLEM 5 — CRITICAL THINKING
A classmate says: "Object.create is pointless now that JavaScript has ES6 classes. You should never use it." Do you agree or disagree? Write 3–4 sentences defending your position, and give at least one scenario where Object.create might be the better choice.

Lesson Summary

Object.create(proto) creates a new, empty object whose internal prototype is set to proto. This establishes a prototype chain — a live link that JavaScript follows when looking up properties the object doesn't own. This process is called delegation, and it means inherited methods like speak() are shared, not copied. When a child object defines a property with the same name as one on its prototype, property shadowing ensures the child's version is used without altering the prototype.

Compared to object literals and constructor functions, Object.create gives you the most explicit control over which object becomes the prototype. It also forms the foundation of ES6 classes, which use prototypes under the hood. By mastering Object.create now, you'll understand the true engine behind JavaScript's object-oriented features and be prepared for advanced patterns like OLOO (Objects Linking to Other Objects).

Varsity Tutors • JavaScript • Object.create — Use Object.create conceptually (intro)