The Old Way
ES5 Functional Version
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hi, I'm " + this.name + " and I'm " + this.age + " years old.");
};
var person1 = new Person("Alice", 30);
person1.greet(); // Hi, I'm Alice and I'm 30 years old.
ES6 Class Version
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`);
}
}
const person1 = new Person("Alice", 30);
person1.greet(); // Hi, I'm Alice and I'm 30 years old.
Constructors: Initializing Object State
A constructor is a special method used to initialize a new instance of a class. When you create a new object with the new
keyword, the constructor runs automatically. This is where you typically assign initial values to fields or perform setup logic.
Example:
class BankCustomer {
constructor(name, accountNumber) {
this.name = name;
this.accountNumber = accountNumber;
}
greet() {
console.log(`Welcome, ${this.name}. Your account number is ${this.accountNumber}.`);
}
}
const customer = new BankCustomer("Jane", "0011223344");
customer.greet(); // Welcome, Jane. Your account number is 0011223344.
Fields: Storing State Within Instances
Fields in JavaScript classes are used to define and store data specific to each instance. Declaring fields makes it easier to see what properties an object will have and can also help enforce default values. Fields can also exist without a constructor when the default values are sufficient.
Example:
class BankBranch {
name = "Main Street Branch";
location = "123 Main St";
info() {
console.log(`${this.name} is located at ${this.location}.`);
}
}
const branch = new BankBranch();
branch.info(); // Main Street Branch is located at 123 Main St.
Methods: Defining Behavior
Methods define the behavior of class instances. They are functions declared inside the class body and can operate on instance data using this
. Methods help encapsulate logic that belongs to a specific object, improving organization and code reuse.
Example:
class ATM {
cashAvailable = 1000;
withdraw(amount) {
if (amount <= this.cashAvailable) {
this.cashAvailable -= amount;
console.log(`Dispensed $${amount}`);
} else {
console.log("Insufficient funds in ATM");
}
}
}
const atm = new ATM();
atm.withdraw(200);
// Dispensed $200
static
: Shared Across All Instances
The static
keyword is used to define fields or methods on the class itself, not on the instances created from it. These members are typically utility functions or data shared across all instances.
When to Use:
- You need a helper function related to the class logic.
- You want a counter or registry that all instances should access.
- You don’t need
this
to refer to an individual object.
Example:
class Bank {
static totalAccounts = 0;
constructor() {
Bank.totalAccounts++;
}
static getTotalAccounts() {
return Bank.totalAccounts;
}
}
const b1 = new Bank();
const b2 = new Bank();
console.log(Bank.getTotalAccounts()); // 2
#private
: True Encapsulation
JavaScript also supports true private fields using the #
symbol. These fields and methods are inaccessible outside of the class body and cannot be tampered with accidentally.
When to Use:
- You want to hide internal details from consumers of the class.
- You’re implementing sensitive logic or internal bookkeeping.
- You want to avoid conflicts with subclass implementations.
Example:
class BankAccount {
#balance = 0;
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
const acc = new BankAccount();
acc.deposit(100);
console.log(acc.getBalance()); // 100
Combining Static and Private
You can use static and private features together for utility and internal state management.
Example:
class BankingSession {
static #sessions = new Map();
static start(sessionId) {
if (!this.#sessions.has(sessionId)) {
this.#sessions.set(sessionId, new BankingSession(sessionId));
}
return this.#sessions.get(sessionId);
}
#id;
constructor(sessionId) {
this.#id = sessionId;
}
getSessionId() {
return this.#id;
}
}
const s1 = BankingSession.start("session-abc");
const s2 = BankingSession.start("session-abc");
console.log(s1 === s2); // true
Summary
- Use constructors to initialize new instances and assign default state.
- Use fields to define and store instance-specific data, either inline or within the constructor.
- Use methods to encapsulate behavior and make objects interactive.
- Use
static
when the data or method applies to the class as a whole, not an individual object. - Use
#private
when data or methods shouldn’t be accessed or modified from outside the class. - Combine static and private members to manage internal state and enforce encapsulation across class-level utilities.
Use these features together to write safer, more expressive class-based code in modern JavaScript.
No comments:
Post a Comment