Think of the Singleton Pattern like a special club that only allows one member. No matter how many times you try to join, you’re always referring to that same, single member. In JavaScript, this means creating a class where you can only ever have one instance (one object created from that class) . This single instance can be accessed from anywhere in your code, making it a global point of access .
This is really useful when you have something that should only exist once, like a settings manager, a logging tool, or maybe a connection to a printer .
Why Use It?
- One and Only One: Guarantees you only get one object from that specific class .
- Easy Access: You can get that single object from anywhere in your program.
- Save Resources: Good for things like database connections where creating many is wasteful .
- Save Memory: Since you reuse the same object, it uses less memory.
Easy JavaScript Examples
Let’s see how to make this happen with simple code.
1. Basic Singleton Class (ES6)
Here’s a straightforward way using a class and a static property.
// Define the Singleton class
class SimpleSingleton {
constructor() {
// Check if an instance already exists
if (SimpleSingleton.instance) {
// If it does, return that existing instance
console.log("Returning existing instance");
return SimpleSingleton.instance;
}
// If not, create properties for the new instance
this.data = "I'm the only one!";
console.log("Creating new instance");
// Store this new instance in the static property
SimpleSingleton.instance = this;
}
getData() {
return this.data;
}
setData(newData) {
this.data = newData;
}
}
// Try creating two instances
console.log("--- Creating first instance ---");
const obj1 = new SimpleSingleton(); // Output: Creating new instance
console.log("--- Creating second instance ---");
const obj2 = new SimpleSingleton(); // Output: Returning existing instance
console.log("--- Checking if they are the same ---");
console.log(obj1 === obj2); // Output: true
console.log("obj1 data:", obj1.getData()); // Output: I'm the only one!
console.log("obj2 data:", obj2.getData()); // Output: I'm the only one!
// Modify data via obj2 and see if obj1 reflects it
obj2.setData("Changed by obj2");
console.log("obj1 data after change:", obj1.getData()); // Output: Changed by obj2
Output:
--- Creating first instance ---
Creating new instance
--- Creating second instance ---
Returning existing instance
--- Checking if they are the same ---
true
obj1 data: I'm the only one!
obj2 data: I'm the only one!
obj1 data after change: Changed by obj2
As you see, obj1
and obj2
are literally the same object. Changing data through one affects the other because they point to the exact same place in memory.
2. Using an Object Literal (Even Simpler)
Sometimes, the simplest singleton is just a plain object. This automatically ensures only one instance exists.
// A simple object literal acts as a singleton
const AppConfig = {
theme: "light",
apiUrl: "https://api.example.com",
getTheme() {
return this.theme;
},
setTheme(newTheme) {
this.theme = newTheme;
}
};
console.log("--- Using the AppConfig singleton ---");
console.log("Initial theme:", AppConfig.getTheme()); // Output: light
AppConfig.setTheme("dark");
console.log("Theme after change:", AppConfig.getTheme()); // Output: dark
// You can't accidentally create a 'new' AppConfig like a class
// const config2 = new AppConfig(); // This would cause an error
// But you can create another variable pointing to the same object:
const configAlias = AppConfig;
console.log("Are they the same?", AppConfig === configAlias); // Output: true
Output:
--- Using the AppConfig singleton ---
Initial theme: light
Theme after change: dark
Are they the same? true
This AppConfig
object is unique and accessible globally. This is the simplest form of a singleton .
Key Takeaway
The Singleton Pattern is a way to ensure you only have one instance of a specific thing in your JavaScript application, providing a global way to access it. You can achieve this using ES6 classes with checks or simply by using a plain object literal.