🏰 JavaScript Class Members: Building Your Kingdom
Imagine you’re building a magical kingdom. Your castle (the class) needs different types of rooms and tools. Some belong to the whole kingdom, some are private chambers, and some are special doorways. Let’s explore each one!
🌟 The Story So Far
You’ve learned how to create classes—blueprints for objects. Now it’s time to fill those blueprints with powerful members: properties and methods that make your classes truly alive.
Think of a class like a toy factory. The factory itself has some things (like the factory name on the building), and each toy made has its own things (like a unique serial number). Let’s see how this works!
📦 Public Class Fields: The Open Playground
What are they? Public class fields are properties you can see and change from anywhere. They’re like toys in an open playground—anyone can play with them!
class Pet {
name = "Buddy"; // public field
age = 2; // public field
greet() {
return `Hi, I'm ${this.name}!`;
}
}
const dog = new Pet();
console.log(dog.name); // "Buddy"
dog.name = "Max"; // ✅ Can change it
console.log(dog.name); // "Max"
🎯 Key Points
- Declared directly in the class body (no
this.needed) - Accessible from outside the class
- Each instance gets its own copy
graph TD A["class Pet"] --> B["name = 'Buddy'"] A --> C["age = 2"] B --> D["Public: Anyone can read/write"] C --> D
🔒 Private Fields & Methods: The Secret Vault
What are they? Private fields start with #. They’re like a secret diary—only the class itself can read or write them!
Why Use Private?
Imagine you have a piggy bank. You don’t want anyone reaching in and taking coins. You want them to use the slot on top (a method). That’s what private fields do!
class BankAccount {
#balance = 0; // Private field
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
#logTransaction(type) { // Private method
console.log(`${type} recorded`);
}
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
// ❌ These won't work!
// account.#balance // Error!
// account.#logTransaction // Error!
🎯 Key Points
- Start with
#symbol - Only accessible inside the class
- Protects data from accidental changes
- Private methods work the same way
graph TD A["BankAccount"] --> B["#balance #40;private#41;"] A --> C["#logTransaction#40;#41; #40;private#41;"] A --> D["deposit#40;#41; #40;public#41;"] A --> E["getBalance#40;#41; #40;public#41;"] D --> B E --> B D --> C
🚪 Getters and Setters: The Smart Doorways
What are they? Getters and setters are special methods that look like properties. They’re like magical doors that can check who’s entering or transform what comes out!
The Problem They Solve
Imagine a thermostat. You don’t want someone setting it to 1000 degrees! Setters let you add rules.
class Thermostat {
#temperature = 20;
// Getter: reads like a property
get temperature() {
return this.#temperature;
}
// Setter: writes like a property
set temperature(value) {
if (value < 0) {
console.log("Too cold!");
return;
}
if (value > 40) {
console.log("Too hot!");
return;
}
this.#temperature = value;
}
}
const thermo = new Thermostat();
console.log(thermo.temperature); // 20 (uses getter)
thermo.temperature = 25; // uses setter
thermo.temperature = 100; // "Too hot!"
console.log(thermo.temperature); // Still 25
🎯 Key Points
getkeyword for readingsetkeyword for writing- Used like regular properties (no parentheses)
- Perfect for validation and computed values
class Circle {
#radius = 5;
get radius() {
return this.#radius;
}
set radius(value) {
if (value > 0) this.#radius = value;
}
// Computed property!
get area() {
return Math.PI * this.#radius ** 2;
}
}
const c = new Circle();
console.log(c.area); // ~78.54
c.radius = 10;
console.log(c.area); // ~314.16
🏛️ Static Properties: The Factory Sign
What are they? Static properties belong to the class itself, not to individual objects. Like the name on a factory building—there’s only one, shared by everyone!
class Car {
static manufacturer = "AutoCorp";
static totalCars = 0;
constructor(model) {
this.model = model;
Car.totalCars++; // Access via class name
}
}
console.log(Car.manufacturer); // "AutoCorp"
console.log(Car.totalCars); // 0
const car1 = new Car("Sedan");
const car2 = new Car("SUV");
console.log(Car.totalCars); // 2
// ❌ Not on instances!
// car1.manufacturer // undefined
🎯 Key Points
- Use
statickeyword - Accessed via class name, not instances
- Perfect for counters, constants, configuration
🛠️ Static Methods: The Factory Tools
What are they? Static methods are tools that belong to the factory, not the toys. They do work related to the class but don’t need a specific instance.
class MathHelper {
static PI = 3.14159;
static square(x) {
return x * x;
}
static isEven(num) {
return num % 2 === 0;
}
}
// Use directly on the class
console.log(MathHelper.PI); // 3.14159
console.log(MathHelper.square(5)); // 25
console.log(MathHelper.isEven(4)); // true
// ❌ No instance needed
// const m = new MathHelper();
// m.square(5) // Error!
🎯 Real-World Example
class User {
static #allUsers = []; // private + static!
constructor(name) {
this.name = name;
User.#allUsers.push(this);
}
static getAllUsers() {
return [...User.#allUsers];
}
static findByName(name) {
return User.#allUsers.find(
u => u.name === name
);
}
}
new User("Alice");
new User("Bob");
console.log(User.getAllUsers());
// [User{name:"Alice"}, User{name:"Bob"}]
console.log(User.findByName("Bob"));
// User{name:"Bob"}
🗺️ The Complete Picture
graph TD A["Class Members"] --> B["Instance Members"] A --> C["Static Members"] B --> D["Public Fields"] B --> E["Private Fields #"] B --> F["Getters/Setters"] B --> G["Methods"] C --> H["Static Properties"] C --> I["Static Methods"] D --> J["Accessible everywhere"] E --> K["Only inside class"] F --> L["Controlled access"] H --> M["Shared by class"] I --> M
🎮 Quick Comparison Table
| Member Type | Syntax | Belongs To | Access |
|---|---|---|---|
| Public Field | name = value |
Instance | Anywhere |
| Private Field | #name = value |
Instance | Inside class only |
| Getter | get name() |
Instance | Like a property |
| Setter | set name(val) |
Instance | Like a property |
| Static Property | static name = value |
Class | Via ClassName |
| Static Method | static name() |
Class | Via ClassName |
🌈 Putting It All Together
class GameCharacter {
// Static: Shared across all characters
static totalCharacters = 0;
static maxHealth = 100;
// Public: Anyone can see
name;
// Private: Protected secrets
#health = GameCharacter.maxHealth;
#secretPower = "invisibility";
constructor(name) {
this.name = name;
GameCharacter.totalCharacters++;
}
// Getter: Read health safely
get health() {
return this.#health;
}
// Setter: Change health with rules
set health(value) {
this.#health = Math.max(0,
Math.min(value, GameCharacter.maxHealth)
);
}
// Private method
#activatePower() {
return `Using ${this.#secretPower}!`;
}
// Public method using private
useSpecialMove() {
return this.#activatePower();
}
// Static method
static getStats() {
return `Total: ${this.totalCharacters}`;
}
}
const hero = new GameCharacter("Luna");
console.log(hero.name); // "Luna"
console.log(hero.health); // 100
hero.health = 150; // Capped to max
console.log(hero.health); // 100
console.log(hero.useSpecialMove());
// "Using invisibility!"
console.log(GameCharacter.getStats());
// "Total: 1"
🎯 Remember This!
- Public fields = Open to everyone
- Private (
#) = Secret, class-only access - Getters = Read with control
- Setters = Write with validation
- Static = Belongs to the class, not instances
You now have all the tools to build powerful, protected, and well-organized classes. Your JavaScript kingdom is ready! 🏰✨
