How JavaScript Objects Work (Prototype Chain, Inheritance & Property Descriptors Explained)

If you're learning JavaScript, one of the most important concepts you will ever understand is JavaScript objects.

You use objects everywhere — storing user data, handling API responses, building applications, even working with the browser itself. But most beginners think objects are just simple key–value pairs.

For example:

const user = {
  name: "Tom",
  age: 19
};

Looks simple, right?

But here’s the truth:

JavaScript objects are much more powerful than they look.

They support inheritance. They have hidden links called prototypes. They allow you to control how properties behave. They even form the foundation of ES6 classes.

In this complete guide, you will learn:

  • What JavaScript objects really are
  • What the prototype chain is
  • How Object.create() works
  • What property descriptors control
  • How getters and setters work
  • How ES6 classes use prototypes
  • What prototype pollution is and how to prevent it

By the end of this article, you will truly understand how JavaScript objects work under the hood.

What Is a JavaScript Object?

A JavaScript object is a collection of properties. Each property has a key (name) and a value.

const student = {
  name: "Ravi",
  grade: 10,
  school: "City High"
};

Here:

  • name is a key
  • "Ravi" is its value

You can:

student.age = 15;      // Add
student.grade = 11;    // Update
delete student.school; // Delete

You can access properties using:

student.name;
student["name"];

So far, everything looks simple.

But here’s something surprising:

Even if you create an empty object like this:

const obj = {};

It already has access to methods like toString() and hasOwnProperty().

Where do these come from?

The answer is the prototype chain.

What Is the Prototype Chain in JavaScript?

JavaScript prototype chain diagram showing property lookup from object to Object.prototype

Every JavaScript object has a hidden link to another object called its prototype.

When JavaScript tries to find a property and cannot find it on the object itself, it automatically looks at its prototype.

This process continues upward until it reaches null. This is called the prototype chain.

const parent = {
  greet() {
    console.log("Hello!");
  }
};

const child = Object.create(parent);

child.greet();

Even though child does not have a greet function, it inherits it from parent.

JavaScript checks in this order:

  1. Check child object
  2. Check parent prototype
  3. Check Object.prototype
  4. Stop at null

This inheritance system is what makes JavaScript powerful and memory-efficient.

If you want to understand how JavaScript objects share properties through inheritance, explore this complete guide on the prototype chain:

Understanding the JavaScript Prototype Chain (Complete Guide with Examples)

How Object.create() Works

Object.create JavaScript inheritance example diagram

Object.create() allows you to create a new object and choose its prototype.

const animal = {
  speak() {
    console.log("Animal sound");
  }
};

const dog = Object.create(animal);
dog.bark = function() {
  console.log("Woof!");
};

dog.speak();

Here, dog inherits from animal.

This is memory-efficient because the speak method is not copied — it is shared through the prototype.

You can also create an object without any prototype:

const pureObject = Object.create(null);

This is useful when you want a clean dictionary object.

If you want to learn more about creating objects in JavaScript and how Object.create() works in real-world scenarios, read this guide:

Object.create() in JavaScript Explained with Practical Examples

What Are Property Descriptors?

JavaScript property descriptor flags writable enumerable configurable

Every property in JavaScript has hidden settings called property descriptors.

These settings control:

  • Whether the value can change (writable)
  • Whether it appears in loops (enumerable)
  • Whether it can be deleted (configurable)

You can control them using Object.defineProperty().

const product = {};

Object.defineProperty(product, "price", {
  value: 500,
  writable: false,
  enumerable: true,
  configurable: false
});

Now the price cannot be changed or deleted.

Getters and Setters in JavaScript

Getters and setters allow you to run code when someone reads or writes a property.

const person = {
  firstName: "John",
  lastName: "Doe"
};

Object.defineProperty(person, "fullName", {
  get() {
    return this.firstName + " " + this.lastName;
  },
  set(value) {
    const parts = value.split(" ");
    this.firstName = parts[0];
    this.lastName = parts[1];
  }
});

Now when you access person.fullName, it automatically combines first and last names.

This is used in modern frameworks for reactivity.

How ES6 Classes Use Prototypes

ES6 classes are built on top of the prototype system.

class User {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log("Hi, I'm " + this.name);
  }
}

The greet method is stored on User.prototype, not inside every object.

So even classes use the prototype chain internally.

What Is Prototype Pollution?

Prototype pollution is a security problem where someone modifies Object.prototype.

If this happens, every object in your application can be affected.

To prevent it:

  • Validate user input carefully
  • Avoid directly merging unknown objects
  • Use Object.create(null) when necessary

Final Thoughts

JavaScript objects are not just data containers. They are powerful structures built on the prototype chain.

Now you understand:

  • How objects store properties
  • How inheritance works
  • How Object.create() controls prototypes
  • How property descriptors control behaviour
  • How getters and setters work
  • How ES6 classes use prototypes
  • How to prevent prototype pollution

Understanding JavaScript objects deeply will make you a stronger developer.

The next time you write {}, remember — there is a powerful system working behind the scenes.

Comments

Popular posts from this blog

What Is This Keyword in JavaScript? Explained With Real Examples

How to Navigate a Large Codebase (Frontend & Backend Guide for New Developers)