In JavaScript, objects can share methods through prototypes. This avoids duplicating the same functions for every object, making code more efficient and memory-friendly. Let’s walk through different versions of how we can model a simple Player object with properties and methods.
Version 1: Direct Object
You define everything inside a single object.
let player = {};
player.name = "John Doe";
player.age = 20;
player.energy = 100;
player.run = function(speed) {
this.energy -= speed;
console.log(this.energy);
};
player.jump = function(height) {
this.energy += height;
console.log(this.energy);
};
✅ Quick to write, ❌ but not reusable for multiple players.
Version 2: Factory Function (Methods inside)
We wrap it in a function that returns an object:
function Player(name, age, energy) {
let player = { name, age, energy };
player.run = function(speed) {
this.energy -= speed;
console.log(this.energy);
};
return player;
}
const player1 = Player("John", 20, 100);
const player2 = Player("Yacine", 21, 100);
player1.run(20); // 80
✅ Reusable function, ❌ but each player gets its own copy of methods.
Version 3: Shared Methods Object
We extract methods into a shared object and assign them:
const playerMethods = {
run: function(speed) {
this.energy -= speed;
console.log(this.energy);
},
jump: function(height) {
this.energy += height;
console.log(this.energy);
}
};
function Player(name, age, energy) {
let player = { name, age, energy };
player.run = playerMethods.run;
player.jump = playerMethods.jump;
return player;
}
✅ Methods are reused, ❌ but assignment is manual and repetitive.
Version 4: Object.create (Prototype-like)
The cleanest approach is to use prototypes:
const playerMethods = {
run: function(speed) {
this.energy -= speed;
console.log(this.energy);
},
jump: function(height) {
this.energy += height;
console.log(this.energy);
},
kickball: function(strength) {
this.energy -= strength;
console.log(this.energy);
}
};
function Player(name, age, energy) {
let player = Object.create(playerMethods); // prototype link
player.name = name;
player.age = age;
player.energy = energy;
return player;
}
const player1 = Player("John Doe", 20, 100);
const player2 = Player("Yacine BGM", 21, 100);
player2.run(20); // 80
player2.jump(10); // 90
✅ Cleaner — all players share methods through the prototype object.
Version 5: Constructor + Prototype
This is the most common pattern before ES6 class. Instead of passing playerMethods, we attach methods directly to Player.prototype.
function Player(name, age, energy) {
let player = Object.create(Player.prototype);
player.name = name;
player.age = age;
player.energy = energy;
return player;
}
// Shared methods live on Player.prototype
Player.prototype.run = function(speed) {
this.energy -= speed;
console.log(this.energy);
};
Player.prototype.jump = function(height) {
this.energy += height;
console.log(this.energy);
};
Player.prototype.kickball = function(strength) {
this.energy -= strength;
console.log(this.energy);
};
const p1 = Player("John Doe", 20, 100);
const p2 = Player("Yacine BGM", 21, 100);
p2.run(20); // 80
p2.jump(10); // 90
✅ Even better