JavaScript Objects & Prototypes Explained — Complete Practical Guide
JavaScript objects are collections of key-value pairs that model real-world things — a user, a product, a car — by bundling related data and behavior together.
What You’ll Learn
- Creating and accessing object properties
- Methods, computed properties, and shorthand syntax
- How
thisworks inside methods - Constructor functions and the
newkeyword - Prototypal inheritance — how objects share behavior
- Getters, setters, and object protection (freeze, seal, preventExtensions)
- Destructuring objects for cleaner code
Why Objects Matter
Objects are the foundation of almost everything in JavaScript — arrays, functions, dates, even classes are objects under the hood. The Doda Browser uses objects to store extension configurations, bookmark data, and user preferences. The Durga Antivirus Pro dashboard models threats as objects with properties like name, severity, status, and methods like quarantine() and delete(). Understanding objects is essential to writing effective JavaScript.
Learning Path
flowchart LR
A[JavaScript Basics] --> B[Arrays]
B --> C[Objects & Prototypes]
C --> D[JSON]
C --> E[Functions]
C --> F[You Are Here]
What Is an Object?
An object is a collection of properties (key-value pairs). Think of it like a filing cabinet drawer labeled with a name, containing related documents:
const person = {
name: 'Alice', // key: "name", value: "Alice"
age: 25, // key: "age", value: 25
greet() { // method — a function stored as a value
console.log(`Hi, I'm ${this.name}`);
}
};Why objects matter: Without objects, you’d store a user’s data in separate variables — userName, userAge, userEmail — with no connection between them. Objects group related data into one package.
Creating Objects
Object Literal (Recommended)
const user = {
name: 'Alice',
age: 25,
role: 'admin'
};Using new Object()
const user = new Object();
user.name = 'Alice';
user.age = 25;The literal syntax ({}) is preferred — it’s shorter, clearer, and more performant.
Accessing Properties
const user = { name: 'Alice', age: 25 };
// Dot notation — when you know the key name
console.log(user.name); // 'Alice'
// Bracket notation — when the key is dynamic or contains special characters
const key = 'name';
console.log(user[key]); // 'Alice'
// Bracket notation for special keys
const obj = { 'full name': 'Alice Smith' };
console.log(obj['full name']); // 'Alice Smith'
Dot vs bracket: Use dot notation by default — it’s cleaner. Use bracket notation when the key is stored in a variable or contains spaces/special characters.
Computed & Shorthand Properties
const key = 'role';
const age = 25;
const user = {
[key]: 'admin', // Computed property — key value is 'role'
name: 'Alice', // Regular property
age, // Shorthand — same as age: age
};Object Methods & this
const user = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`);
},
greetArrow: () => {
console.log(`Hello, ${this.name}`); // this is NOT the object!
}
};
user.greet(); // 'Hello, Alice'
user.greetArrow(); // 'Hello, undefined'
Critical: Arrow functions and this. Arrow functions don’t have their own this — they inherit it from the surrounding scope. For object methods, always use regular function syntax (greet() {}), not arrow functions.
Constructor Functions & new
Constructor functions create multiple objects with the same structure:
function Car(make, model) {
this.make = make;
this.model = model;
}
const myCar = new Car('Toyota', 'Camry');
const yourCar = new Car('Honda', 'Civic');
console.log(myCar.make); // 'Toyota'
console.log(yourCar.model); // 'Civic'
What new does (4 steps):
- Creates a new empty object
{} - Sets the prototype of that object to
Car.prototype - Calls
Carwiththisbound to the new object - Returns the new object
Anticipating confusion: If you forget new, this inside Car points to the global object (window in browsers, global in Node.js). This pollutes the global scope silently. Always use new with constructor functions.
Prototypal Inheritance
Every JavaScript object has a hidden [[Prototype]] — like a backup parent that the object inherits properties from:
const animal = { eats: true };
const rabbit = { jumps: true };
// Set animal as rabbit's prototype
rabbit.__proto__ = animal;
console.log(rabbit.jumps); // true — own property
console.log(rabbit.eats); // true — inherited from animal
How the prototype chain works: When you access rabbit.eats, JavaScript first checks if rabbit has an eats property. It doesn’t, so it looks at rabbit.__proto__ (which is animal). Animal has eats, so it returns true.
flowchart LR
A[rabbit] -->|__proto__| B[animal]
B -->|__proto__| C[Object.prototype]
C -->|__proto__| D[null]
A -.->|inherits| E[eats]
Modern way: Use Object.create() instead of __proto__:
const rabbit = Object.create(animal);
rabbit.jumps = true;Getters & Setters
Getters and setters let you define computed properties that look like regular properties but execute logic:
const user = {
firstName: 'Alice',
lastName: 'Smith',
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(value) {
[this.firstName, this.lastName] = value.split(' ');
}
};
console.log(user.fullName); // 'Alice Smith' — getter runs
user.fullName = 'Bob Jones'; // setter runs
console.log(user.firstName); // 'Bob'
Object Protection
const obj = { a: 1 };
Object.preventExtensions(obj); // Can't add new properties
Object.seal(obj); // Can't add or delete — can modify existing
Object.freeze(obj); // Can't add, delete, or modify (shallow)
console.log(Object.isSealed(obj)); // true
console.log(Object.isFrozen(obj)); // true
When to freeze: Configuration objects, constants, and enum-like values should be frozen to prevent accidental modification.
Destructuring
const user = { name: 'Alice', age: 25, city: 'NYC' };
// Basic destructuring
const { name, age } = user;
console.log(name, age); // Alice 25
// Rename variables
const { name: userName, age: userAge } = user;
// Default values
const { name, role = 'user' } = user;
// Nested destructuring
const person = { name: 'Alice', address: { city: 'NYC' } };
const { address: { city } } = person;
console.log(city); // 'NYC'
// Rest pattern
const { name, ...rest } = user;
console.log(rest); // { age: 25, city: 'NYC' }
Common Mistakes
1. Mutating objects when you meant to copy
const a = { x: 1 };
const b = a;
b.x = 2;
console.log(a.x); // 2 — b is a reference, not a copy!
Fix: Use const copy = { ...original } for shallow copy or structuredClone(original) for deep copy.
2. Using for...in without checking hasOwnProperty
for (const key in obj) {
if (obj.hasOwnProperty(key)) { } // Skip inherited properties
}Better: Use Object.keys(obj).forEach() or for...of Object.entries(obj).
3. Forgetting new with constructors
const car = Car('Toyota', 'Camry'); // this → window (global pollution)
Constructor functions must be called with new. Consider using classes instead.
4. Arrow functions as methods
Arrow functions don’t have their own this. Use regular functions for object methods.
5. Shallow vs deep copy confusion
const copy = { ...original }; // Shallow — nested objects are still shared
Use structuredClone(original) for deep cloning.
Practice Questions
What’s the difference between dot notation and bracket notation for property access? Dot notation requires a literal key name. Bracket notation accepts a string or variable, allowing dynamic keys.
What does
thisrefer to inside an arrow function in an object? It inheritsthisfrom the enclosing scope, not the object. Use regular functions for methods.How does prototypal inheritance work? If a property isn’t found on the object, JavaScript looks up the prototype chain until it reaches
null.What’s the difference between
Object.freeze()andObject.seal()? Freeze prevents all changes (add, delete, modify). Seal prevents add/delete but allows modification of existing properties.
Challenge: Build a createUser factory function that returns an object with name, email, and a greet() method. Then use Object.freeze() to protect the email from modification.
FAQ
Try It Yourself
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Objects Playground</title>
<style>
body { font-family: Arial, sans-serif; padding: 2rem; }
pre { background: #f4f4f4; padding: 1rem; border-radius: 5px; }
</style>
</head>
<body>
<h1>Objects Sandbox</h1>
<pre id="output"></pre>
<script>
const out = document.getElementById('output');
let result = '';
// Create an object
const product = {
name: 'Widget',
price: 19.99,
inStock: true,
discount(percent) {
return this.price * (1 - percent / 100);
}
};
result += `Product: ${product.name}\n`;
result += `Price: $${product.price}\n`;
result += `10% off: $${product.discount(10).toFixed(2)}\n\n`;
// Destructuring
const { name, price } = product;
result += `Destructured: ${name} - $${price}\n\n`;
// Object keys/values
result += 'All properties:\n';
Object.entries(product).forEach(([key, value]) => {
result += ` ${key}: ${value}\n`;
});
out.textContent = result;
</script>
</body>
</html>What’s Next
Now that you understand objects, move on to JSON and advanced collections:
| Lesson | Description |
|---|---|
| JavaScript Home | Back to the JavaScript hub |
| https://tutorials.dodatech.com/programming-languages/javascript/js-json/ | JSON — serialize objects for data exchange |
| https://tutorials.dodatech.com/programming-languages/javascript/js-collections/ | Sets, Maps & Iterables — advanced data structures |
| https://tutorials.dodatech.com/programming-languages/javascript/js-functions/ | Functions & Scope — functions as objects |
| React Props | Passing objects as props in React |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
What’s Next
Congratulations on completing this Js Objects tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro