OOP in JavaScript
Getter & Setter Accessors
Master accessors in JavaScript. Learn to declare getters and setters, implement data validation, and calculate dynamic properties.
1. Introduction
In Object-Oriented Programming, exposing class properties directly can lead to unintended mutations. JavaScript solves this using Getter & Setter Accessor Methods, allowing you to execute code when reading or writing to a property while presenting it as a standard object property from the outside.
2. Why It Matters
Accessors allow you to implement validation or calculate dynamic properties automatically. For example, you can validate that an email address is formatted correctly before saving it, or calculate a user's full name from separate first and last name fields dynamically.
3. Real-World Analogy
Think of a Thermostat Temperature Controller:
- Direct Access (Touching the furnace directly): If a visitor wants to change the room temperature, they walk to the furnace, turn the knobs, and adjust the pressure. If they make a mistake, they could overheat the building.
- Getter / Setter Accessors (Thermostat interface): You install a thermostat controller on the wall.
1. When they check the temperature (getter), the thermostat displays the value on the screen.
2. When they adjust the dial (setter), the thermostat validates the input: "If the setting is below 50 degrees or above 90 degrees, ignore the request (validation guard)". It sits between the user and the system, protecting the hardware.
4. Getters and Setters Syntax
Accessors are defined using the get and set keywords inside the class body. By convention, internal storage properties are prefixed with an underscore (_) or declared as private fields (#) to prevent recursion errors:
5. Architectural Details
- No Parentheses: Accessors are invoked like properties (e.g.
user.fullName), not function calls (e.g.user.fullName()). - Prototype Storage: Accessors are defined on the class's prototype object, making them available to all instances.
- Validation Barriers: Setters act as gatekeepers, validating inputs before writing them to internal fields.
6. Practical Example
This script demonstrates implementing validation inside a setter to restrict values to a specific range:
7. Common Mistakes
- Creating infinite recursion loops inside accessors: Naming your accessor method the exact same name as the internal property it reads or writes to (e.g.
this.name = nameinsideset name(val)) causes the setter to call itself recursively, crashing with a RangeError (Maximum call stack size exceeded). Always use a separate internal storage key (like_nameor#name).
8. Quick Quiz
Q1: How do you read a getter accessor property on a class instance?
A) By calling it like a method: instance.propName()
B) By accessing it like a standard property: instance.propName
Answer: B — Accessors are invoked like standard properties, without parentheses.
9. Scenario-Based Challenge
The Encapsulated Currency Formatter:
A financial transaction class stores a value in cents: _cents = 1000. You want users to be able to read and write values in dollars: 10.00 using a property price. Write the getter and setter conversion logic.
10. Debugging Exercise
Explain why this accessor crashes with a Maximum call stack size exceeded error, and how to fix it:
class UserAccount { constructor(name) { this.name = name; }get name() { return this.name; // Bug: recursive call! }
set name(val) { this.name = val; // Bug: recursive call stack overflow! } } const account = new UserAccount('Alice'); // crashes! Why?
View Solution
Diagnosis: The getter and setter name matches the property identifier they access (this.name), causing the setter to call itself recursively until the call stack overflows.
Fix: Use a separate private field or underscore-prefixed property (like #name or _name) to store the internal value:
class UserAccount { #name; // Private storage keyconstructor(name) { this.name = name; // Calls setter }
get name() { return this.#name; // Reads from private storage }
set name(val) { this.#name = val; // Writes to private storage } }
11. Interview Questions
🟢 Q1: Explain why getters and setters are useful in JavaScript class architecture.
Answer: Getters and setters provide a way to define properties that run code when they are read or written to, while presenting them as standard properties from the outside.
They are useful because:
• Data Validation: Setters act as gatekeepers, validating inputs before writing them to internal fields.
• Encapsulation: They allow you to hide internal implementation details (such as storing values in cents while exposing them in dollars).
• Computed Properties: They allow you to calculate properties dynamically (like combining first and last name fields) without needing to write custom method calls.
12. Production Considerations
- • Avoid Heavy Operations: Accessors are expected to be fast because they are invoked like standard property lookups. Avoid writing heavy calculations, database queries, or network requests inside getters or setters. If a property requires heavy processing, define it as a standard method instead.