Mastering JavaScript Objects and Prototypal Inheritance
Introduction to JavaScript Objects
In JavaScript, an object is a self-contained environment that stores data as a collection of properties and methods. A property is an association between a name (or key) and a value, while a method is a function associated with an object.
Think of an object as a real-world entity. For example, a Car is an object. It has properties like color, brand, and weight, and methods like start, drive, and brake.
// A simple conceptual look at an object
let car = {
brand: "Tesla", // Property (key: value)
color: "Red", // Property
start: function() { // Method
console.log("Engine started!");
}
};Types of Objects in JavaScript
While almost everything in JavaScript is an object (or acts like one), they generally fall into three main categories:
1. Native / Built-in Objects
These are standard objects provided by JavaScript out of the box as part of the language specification:
- Data Structures: Object, Array, Map, Set
- Utility Objects: Math, Date, RegExp (Regular Expressions), JSON
2. Host Objects
These are supplied by the environment running JavaScript (like a web browser or Node.js):
- Browser Environment (Web APIs): window, document (DOM), history, fetch
- Node.js Environment: process, fs (File System), path
3. User-Defined Objects
These are custom objects created by you, the developer, to suit your specific application needs.
Creating Objects in JavaScript
There are several ways to create objects in JavaScript:
1. Object Literal
The simplest and most readable way to create an object is using curly braces {}.
const user = {
firstName: "Jane",
lastName: "Doe",
age: 28
};2. Using the new Object() Syntax
You can use the built-in Object constructor, though this is generally less preferred than the literal syntax.
const user = new Object();
user.firstName = "Jane";
user.lastName = "Doe";
user.age = 28;3. Constructor Functions
Useful when you need a blueprint to create multiple objects of the same type. Conventionally, constructor functions start with a capital letter.
function Person(first, last, age) {
this.firstName = first;
this.lastName = last;
this.age = age;
}
// Creating instances
const user1 = new Person("Jane", "Doe", 28);
const user2 = new Person("John", "Smith", 34);4. Object.create()
This method creates a new object, using an existing object as the prototype of the newly created object.
const protoUser = {
greeting: function() {
return `Hello, my name is ${this.name}`;
}
};
const user = Object.create(protoUser);
user.name = "Jane"; // Inherits the greeting methodObject Methods
A method is simply a property containing a function definition. Methods allow objects to “do” things.
Defining Methods
You can define methods inside an object literal in two ways:
const calculator = {
// Traditional way
add: function(a, b) {
return a + b;
},
// Modern ES6 shorthand (Recommended)
subtract(a, b) {
return a - b;
}
};
console.log(calculator.add(5, 3)); // Output: 8
console.log(calculator.subtract(5, 3)); // Output: 2Constructor Functions and the ‘new’ Keyword
A Constructor Function is a regular function used as a blueprint to create multiple objects of the same type. To create an instance, we use the new keyword.
function Player(name, level) {
this.name = name;
this.level = level;
}
const player1 = new Player("Nova", 5);
console.log(player1.name); // Output: NovaWhat happens when the ‘new’ keyword is used?
- A new empty object {} is created.
- The
thiskeyword is bound to this new object. - The code inside the constructor function executes, assigning properties to
this. - The newly created object is automatically returned.
Prototypes in JavaScript
Every function and object has a built-in property called a Prototype. Prototypes are the mechanism by which JavaScript objects inherit features from one another.
- Function.prototype: The blueprint assigned as the prototype to any objects created by this function using the
newkeyword. - [[Prototype]] (or __proto__): An internal hidden link pointing to an object’s constructor’s prototype.
Attaching methods to the prototype instead of the constructor saves memory:
function Player(name, level) {
this.name = name;
this.level = level;
}
Player.prototype.levelUp = function() {
this.level++;
console.log(`${this.name} advanced to level ${this.level}!`);
};
const player1 = new Player("Nova", 5);
player1.levelUp(); // Output: Nova advanced to level 6!Inheritance Using the Prototype Chain
When you access a property or method, JavaScript looks for it on the object, then its prototype, and so on. This sequence is the Prototype Chain.
Implementing Prototypal Inheritance
// 1. Parent Constructor
function Character(name) {
this.name = name;
}
Character.prototype.greet = function() {
return `Hello, I am ${this.name}`;
};
// 2. Child Constructor
function Mage(name, spell) {
Character.call(this, name);
this.spell = spell;
}
// 3. Link prototypes
Mage.prototype = Object.create(Character.prototype);
// 4. Reset the constructor pointer
Mage.prototype.constructor = Mage;
// 5. Add unique methods
Mage.prototype.castSpell = function() {
return `${this.name} casts ${this.spell}!`;
};
const gandalf = new Mage("Gandalf", "Fireball");
console.log(gandalf.greet()); // Output: Hello, I am Gandalf
console.log(gandalf.castSpell()); // Output: Gandalf casts Fireball!