JavaScript tutorials > Objects and Arrays > Objects > What are getters and setters in JavaScript objects?
What are getters and setters in JavaScript objects?
Getters and setters are special methods within JavaScript objects that allow you to control how object properties are accessed and modified. They provide a way to encapsulate the logic behind getting and setting a property's value, enabling you to add validation, calculations, or other custom behavior. This tutorial provides clear explanation with code snippets.
Basic Getters and Setters Example
This example demonstrates a simple object person
with a getter and a setter for the fullName
property. The getter concatenates the firstName
and lastName
properties. The setter splits the input name into first and last names and updates the corresponding properties.
const person = {
firstName: 'John',
lastName: 'Doe',
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
const parts = name.split(' ');
this.firstName = parts[0];
this.lastName = parts[1];
}
};
console.log(person.fullName); // Output: John Doe
person.fullName = 'Jane Smith';
console.log(person.firstName); // Output: Jane
console.log(person.lastName); // Output: Smith
Concepts Behind the Snippet
Getters use the get
keyword, and setters use the set
keyword. These keywords define special methods that execute when you try to access (getter) or assign (setter) a property. They enable encapsulation by controlling access to the underlying data. The this
keyword refers to the object on which the getter/setter is defined.
Real-Life Use Case: Validation
This example demonstrates how setters can be used to validate input. The radius
setter ensures that the radius is always a positive number. If an invalid value is assigned, an error is thrown. Note that we are using `_radius` to store the actual value to avoid an infinite recursion call. The getter is used to retrieve the actual value of the private `_radius` property.
const circle = {
radius: 1,
set radius(value) {
if (value <= 0) {
throw new Error('Radius must be positive');
}
this._radius = value; // Use a private property to store the actual value
},
get radius(){
return this._radius;
},
get area() {
return Math.PI * this._radius * this._radius;
}
};
circle.radius = 5; // Valid
console.log(circle.area);
//circle.radius = -1; // Throws an error
Best Practices
Always validate input in setters to maintain data integrity. Use a naming convention (like prefixing with an underscore, e.g., _propertyName
) to differentiate between the public property name and the internal variable used to store the data. Avoid performing computationally expensive operations in getters to ensure good performance. Keep getter and setter logic simple and focused on their respective tasks.
Interview Tip
When discussing getters and setters in an interview, be sure to mention their role in encapsulation and data validation. Explain how they provide a controlled interface for accessing and modifying object properties. Be prepared to provide examples of real-world use cases, such as validating input or performing calculations.
When to Use Them
Use getters and setters when you need to control how a property is accessed or modified. This is particularly useful when you need to validate input, perform calculations, or trigger side effects. If a property is simple and doesn't require any special logic, you might not need a getter or setter.
Memory Footprint
Getters and setters themselves introduce a small memory overhead, as they are essentially functions associated with the object. However, this overhead is usually negligible unless you have a very large number of objects with complex getters and setters. The primary impact on memory footprint comes from the data stored within the object and any additional variables used within the getter and setter logic. When using the best practice to use a private property to store the data, it will take up the memory space to hold the value of that private property.
Alternatives
Without getters and setters, you could directly access and modify object properties. However, this approach lacks encapsulation and doesn't allow you to easily add validation or custom logic later on. You could also use methods (e.g., setName(firstName, lastName)
and getFullName()
) to achieve similar results, but getters and setters provide a more concise and intuitive syntax for property access.
Pros
Encapsulation: Getters and setters encapsulate the logic behind property access and modification, hiding the internal implementation details from the outside world. Data Validation: Setters allow you to validate input before assigning it to a property, ensuring data integrity. Controlled Access: You can control which properties are read-only (getter only) or write-only (setter only). Flexibility: You can modify the internal implementation of a property without affecting the code that uses the object, as long as the getter and setter interfaces remain the same.
Cons
Complexity: Getters and setters can add complexity to your code, especially if they involve complex logic. Performance Overhead: While usually negligible, getters and setters can introduce a small performance overhead compared to direct property access. Readability: Overuse of getters and setters can sometimes make code less readable, especially if they are used for simple properties that don't require any special logic.
FAQ
-
Why use a private property (e.g., _radius) in a setter?
Using a private property prevents infinite recursion. If the setter tried to set the original `radius` property, it would call itself repeatedly, leading to a stack overflow. -
Can I have a getter without a setter, or a setter without a getter?
Yes. A getter without a setter makes the property read-only. A setter without a getter makes the property write-only, although this is less common. -
Are getters and setters supported in all browsers?
Yes, getters and setters are widely supported in modern browsers and Node.js.