~/
hackweb.dev
JavaScript Getters, Setters & Encapsulation
Quiz
⌘K
...
~/
/tutorials
/js/js-getters-setters/edit
~ Contribute
Suggest a correction or improvement. The author reviews it before it goes live.
Loading...
Comment
0 / 300
Typo
Grammar
Broken link
Clarify
Code
en/tutorials/js/22js-getters-setters
Write
Preview
Diff
# JavaScript Getters, Setters & Encapsulation Control access to object properties and validate data using getters and setters. ## Basic Getters and Setters ```javascript class Temperature { #celsius; constructor(celsius) { this.celsius = celsius; } get celsius() { return this.#celsius; } set celsius(value) { if (value < -273.15) throw new Error("Below absolute zero!"); this.#celsius = value; } get fahrenheit() { return (this.#celsius * 9/5) + 32; } set fahrenheit(value) { this.celsius = (value - 32) * 5/9; } } let temp = new Temperature(100); console.log(temp.fahrenheit); // 212 temp.fahrenheit = 32; console.log(temp.celsius); // 0 ``` - `get` — Runs when you read the property - `set` — Runs when you assign a value ## Validation in Setters ```javascript class User { #name; #email; constructor(name, email) { this.name = name; this.email = email; } get name() { return this.#name; } set name(v) { if (!v || v.trim().length < 2) throw new Error("Name too short"); this.#name = v.trim(); } get email() { return this.#email; } set email(v) { if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) throw new Error("Invalid email"); this.#email = v.toLowerCase(); } } let user = new User("John", "JOHN@EXAMPLE.COM"); console.log(user.email); // "john@example.com" ``` **Remember:** Setters run on assignment — `this.name = "J"` triggers the setter. ## Computed Properties Getters calculate values on demand — always in sync: ```javascript class Rectangle { #w; #h; constructor(w, h) { this.w = w; this.h = h; } get w() { return this.#w; } set w(v) { if (v <= 0) throw new Error("Must be positive"); this.#w = v; } get h() { return this.#h; } set h(v) { if (v <= 0) throw new Error("Must be positive"); this.#h = v; } get area() { return this.#w * this.#h; } get isSquare() { return this.#w === this.#h; } } let rect = new Rectangle(4, 6); console.log(rect.area); // 24 console.log(rect.isSquare); // false ``` **Tip:** Computed properties stay in sync — no need to update them when data changes. ## Complete Example: Bank Account ```javascript class BankAccount { #balance; #transactions = []; constructor(owner, initialBalance = 0) { this.owner = owner; this.#balance = initialBalance; } get balance() { return this.#balance; } get transactions() { return [...this.#transactions]; } deposit(amount) { if (amount <= 0) throw new Error("Amount must be positive"); this.#balance += amount; this.#transactions.push({ type: "deposit", amount }); return this; } withdraw(amount) { if (amount <= 0) throw new Error("Amount must be positive"); if (amount > this.#balance) throw new Error("Insufficient funds"); this.#balance -= amount; this.#transactions.push({ type: "withdrawal", amount }); return this; } } let account = new BankAccount("John", 1000); account.deposit(500).withdraw(200); console.log(account.balance); // 1300 ``` **Remember:** `transactions` returns a copy — external code can't mutate the internal array. ## Best Practices - **Use getters for computed values** — Calculate on demand - **Use setters for validation** — Protect data integrity - **Use private fields** — Encapsulate implementation details - **Return copies from getters** — Prevent external mutation ## Common Mistakes - **Infinite recursion** — A getter calling itself - **Forgetting validation** — Invalid data enters the object - **Mutating returned objects** — Return copies instead - **Not handling null/undefined** — Check in setters
No changes yet
Reset to original
Submit suggestion
cancel